Repeat mode UI
Added repeat mode toggle buttons to UI. Current mode gets forwarded to Exoplayer instance, but without playback behaviour changes yet. Translations for button descriptions are also missing - this will be another CL. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=155386549
@ -470,6 +470,10 @@ import java.util.Locale;
|
|||||||
switch (repeatMode) {
|
switch (repeatMode) {
|
||||||
case ExoPlayer.REPEAT_MODE_OFF:
|
case ExoPlayer.REPEAT_MODE_OFF:
|
||||||
return "OFF";
|
return "OFF";
|
||||||
|
case ExoPlayer.REPEAT_MODE_ONE:
|
||||||
|
return "ONE";
|
||||||
|
case ExoPlayer.REPEAT_MODE_ALL:
|
||||||
|
return "ALL";
|
||||||
default:
|
default:
|
||||||
return "?";
|
return "?";
|
||||||
}
|
}
|
||||||
|
@ -268,12 +268,20 @@ public interface ExoPlayer {
|
|||||||
* Repeat modes for playback.
|
* Repeat modes for playback.
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({REPEAT_MODE_OFF})
|
@IntDef({REPEAT_MODE_OFF, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
|
||||||
public @interface RepeatMode {}
|
public @interface RepeatMode {}
|
||||||
/**
|
/**
|
||||||
* Normal playback without repetition.
|
* Normal playback without repetition.
|
||||||
*/
|
*/
|
||||||
int REPEAT_MODE_OFF = 0;
|
int REPEAT_MODE_OFF = 0;
|
||||||
|
/**
|
||||||
|
* "Repeat One" mode to repeat the currently playing window infinitely.
|
||||||
|
*/
|
||||||
|
int REPEAT_MODE_ONE = 1;
|
||||||
|
/**
|
||||||
|
* "Repeat All" mode to repeat the entire timeline infinitely.
|
||||||
|
*/
|
||||||
|
int REPEAT_MODE_ALL = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a listener to receive events from the player. The listener's methods will be called on
|
* Register a listener to receive events from the player. The listener's methods will be called on
|
||||||
|
@ -18,13 +18,17 @@ package com.google.android.exoplayer2.ui;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.support.annotation.IntDef;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
@ -35,6 +39,8 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -70,6 +76,14 @@ import java.util.Locale;
|
|||||||
* <li>Default: {@link #DEFAULT_FAST_FORWARD_MS}</li>
|
* <li>Default: {@link #DEFAULT_FAST_FORWARD_MS}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </li>
|
* </li>
|
||||||
|
* <li><b>{@code repeat_toggle_modes}</b> - A flagged enumeration value specifying which repeat
|
||||||
|
* mode toggle options are enabled. Valid values are: {@code none}, {@code one},
|
||||||
|
* {@code all}, or {@code one|all}.
|
||||||
|
* <ul>
|
||||||
|
* <li>Corresponding method: {@link #setRepeatToggleModes(int)}</li>
|
||||||
|
* <li>Default: {@link #DEFAULT_REPEAT_TOGGLE_MODES}</li>
|
||||||
|
* </ul>
|
||||||
|
* </li>
|
||||||
* <li><b>{@code controller_layout_id}</b> - Specifies the id of the layout to be inflated. See
|
* <li><b>{@code controller_layout_id}</b> - Specifies the id of the layout to be inflated. See
|
||||||
* below for more details.
|
* below for more details.
|
||||||
* <ul>
|
* <ul>
|
||||||
@ -117,6 +131,11 @@ import java.util.Locale;
|
|||||||
* <li>Type: {@link View}</li>
|
* <li>Type: {@link View}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </li>
|
* </li>
|
||||||
|
* <li><b>{@code exo_repeat_toggle}</b> - The repeat toggle button.
|
||||||
|
* <ul>
|
||||||
|
* <li>Type: {@link View}</li>
|
||||||
|
* </ul>
|
||||||
|
* </li>
|
||||||
* <li><b>{@code exo_position}</b> - Text view displaying the current playback position.
|
* <li><b>{@code exo_position}</b> - Text view displaying the current playback position.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Type: {@link TextView}</li>
|
* <li>Type: {@link TextView}</li>
|
||||||
@ -189,6 +208,14 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
*/
|
*/
|
||||||
boolean dispatchSeekTo(ExoPlayer player, int windowIndex, long positionMs);
|
boolean dispatchSeekTo(ExoPlayer player, int windowIndex, long positionMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches a {@link ExoPlayer#setRepeatMode(int)} operation.
|
||||||
|
*
|
||||||
|
* @param player The player to which the operation should be dispatched.
|
||||||
|
* @param repeatMode The repeat mode.
|
||||||
|
* @return True if the operation was dispatched. False if suppressed.
|
||||||
|
*/
|
||||||
|
boolean dispatchSetRepeatMode(ExoPlayer player, @ExoPlayer.RepeatMode int repeatMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,11 +236,38 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchSetRepeatMode(ExoPlayer player, @ExoPlayer.RepeatMode int repeatMode) {
|
||||||
|
player.setRepeatMode(repeatMode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of repeat toggle modes. Can be combined using bit-wise operations.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef(flag = true, value = {REPEAT_TOGGLE_MODE_NONE, REPEAT_TOGGLE_MODE_ONE,
|
||||||
|
REPEAT_TOGGLE_MODE_ALL})
|
||||||
|
public @interface RepeatToggleModes {}
|
||||||
|
/**
|
||||||
|
* All repeat mode buttons disabled.
|
||||||
|
*/
|
||||||
|
public static final int REPEAT_TOGGLE_MODE_NONE = 0;
|
||||||
|
/**
|
||||||
|
* "Repeat One" button enabled.
|
||||||
|
*/
|
||||||
|
public static final int REPEAT_TOGGLE_MODE_ONE = 1;
|
||||||
|
/**
|
||||||
|
* "Repeat All" button enabled.
|
||||||
|
*/
|
||||||
|
public static final int REPEAT_TOGGLE_MODE_ALL = 2;
|
||||||
|
|
||||||
public static final int DEFAULT_FAST_FORWARD_MS = 15000;
|
public static final int DEFAULT_FAST_FORWARD_MS = 15000;
|
||||||
public static final int DEFAULT_REWIND_MS = 5000;
|
public static final int DEFAULT_REWIND_MS = 5000;
|
||||||
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
|
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
|
||||||
|
public static final @RepeatToggleModes int DEFAULT_REPEAT_TOGGLE_MODES = REPEAT_TOGGLE_MODE_NONE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of windows that can be shown in a multi-window time bar.
|
* The maximum number of windows that can be shown in a multi-window time bar.
|
||||||
@ -229,6 +283,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
private final View pauseButton;
|
private final View pauseButton;
|
||||||
private final View fastForwardButton;
|
private final View fastForwardButton;
|
||||||
private final View rewindButton;
|
private final View rewindButton;
|
||||||
|
private final ImageView repeatToggleButton;
|
||||||
private final TextView durationView;
|
private final TextView durationView;
|
||||||
private final TextView positionView;
|
private final TextView positionView;
|
||||||
private final TimeBar timeBar;
|
private final TimeBar timeBar;
|
||||||
@ -237,6 +292,13 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
private final Timeline.Period period;
|
private final Timeline.Period period;
|
||||||
private final Timeline.Window window;
|
private final Timeline.Window window;
|
||||||
|
|
||||||
|
private final Drawable repeatOffButtonDrawable;
|
||||||
|
private final Drawable repeatOneButtonDrawable;
|
||||||
|
private final Drawable repeatAllButtonDrawable;
|
||||||
|
private final String repeatOffButtonContentDescription;
|
||||||
|
private final String repeatOneButtonContentDescription;
|
||||||
|
private final String repeatAllButtonContentDescription;
|
||||||
|
|
||||||
private ExoPlayer player;
|
private ExoPlayer player;
|
||||||
private ControlDispatcher controlDispatcher;
|
private ControlDispatcher controlDispatcher;
|
||||||
private VisibilityListener visibilityListener;
|
private VisibilityListener visibilityListener;
|
||||||
@ -248,6 +310,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
private int rewindMs;
|
private int rewindMs;
|
||||||
private int fastForwardMs;
|
private int fastForwardMs;
|
||||||
private int showTimeoutMs;
|
private int showTimeoutMs;
|
||||||
|
private @RepeatToggleModes int repeatToggleModes;
|
||||||
private long hideAtMs;
|
private long hideAtMs;
|
||||||
private long[] adBreakTimesMs;
|
private long[] adBreakTimesMs;
|
||||||
|
|
||||||
@ -280,6 +343,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
rewindMs = DEFAULT_REWIND_MS;
|
rewindMs = DEFAULT_REWIND_MS;
|
||||||
fastForwardMs = DEFAULT_FAST_FORWARD_MS;
|
fastForwardMs = DEFAULT_FAST_FORWARD_MS;
|
||||||
showTimeoutMs = DEFAULT_SHOW_TIMEOUT_MS;
|
showTimeoutMs = DEFAULT_SHOW_TIMEOUT_MS;
|
||||||
|
repeatToggleModes = DEFAULT_REPEAT_TOGGLE_MODES;
|
||||||
if (attrs != null) {
|
if (attrs != null) {
|
||||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
||||||
R.styleable.PlaybackControlView, 0, 0);
|
R.styleable.PlaybackControlView, 0, 0);
|
||||||
@ -290,6 +354,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
showTimeoutMs = a.getInt(R.styleable.PlaybackControlView_show_timeout, showTimeoutMs);
|
showTimeoutMs = a.getInt(R.styleable.PlaybackControlView_show_timeout, showTimeoutMs);
|
||||||
controllerLayoutId = a.getResourceId(R.styleable.PlaybackControlView_controller_layout_id,
|
controllerLayoutId = a.getResourceId(R.styleable.PlaybackControlView_controller_layout_id,
|
||||||
controllerLayoutId);
|
controllerLayoutId);
|
||||||
|
repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes);
|
||||||
} finally {
|
} finally {
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
@ -335,6 +400,26 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
if (fastForwardButton != null) {
|
if (fastForwardButton != null) {
|
||||||
fastForwardButton.setOnClickListener(componentListener);
|
fastForwardButton.setOnClickListener(componentListener);
|
||||||
}
|
}
|
||||||
|
repeatToggleButton = (ImageView) findViewById(R.id.exo_repeat_toggle);
|
||||||
|
if (repeatToggleButton != null) {
|
||||||
|
repeatToggleButton.setOnClickListener(componentListener);
|
||||||
|
}
|
||||||
|
Resources resources = context.getResources();
|
||||||
|
repeatOffButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_off);
|
||||||
|
repeatOneButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_one);
|
||||||
|
repeatAllButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_all);
|
||||||
|
repeatOffButtonContentDescription = resources.getString(
|
||||||
|
R.string.exo_controls_repeat_off_description);
|
||||||
|
repeatOneButtonContentDescription = resources.getString(
|
||||||
|
R.string.exo_controls_repeat_one_description);
|
||||||
|
repeatAllButtonContentDescription = resources.getString(
|
||||||
|
R.string.exo_controls_repeat_all_description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ResourceType")
|
||||||
|
private static @RepeatToggleModes int getRepeatToggleModes(TypedArray a,
|
||||||
|
@RepeatToggleModes int repeatToggleModes) {
|
||||||
|
return a.getInt(R.styleable.PlaybackControlView_repeat_toggle_modes, repeatToggleModes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -440,6 +525,37 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
this.showTimeoutMs = showTimeoutMs;
|
this.showTimeoutMs = showTimeoutMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns which repeat toggle modes are enabled.
|
||||||
|
*
|
||||||
|
* @return The currently enabled {@link RepeatToggleModes}.
|
||||||
|
*/
|
||||||
|
public @RepeatToggleModes int getRepeatToggleModes() {
|
||||||
|
return repeatToggleModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which repeat toggle modes are enabled.
|
||||||
|
*
|
||||||
|
* @param repeatToggleModes A set of {@link RepeatToggleModes}.
|
||||||
|
*/
|
||||||
|
public void setRepeatToggleModes(@RepeatToggleModes int repeatToggleModes) {
|
||||||
|
this.repeatToggleModes = repeatToggleModes;
|
||||||
|
if (player != null) {
|
||||||
|
@ExoPlayer.RepeatMode int currentMode = player.getRepeatMode();
|
||||||
|
if (repeatToggleModes == REPEAT_TOGGLE_MODE_NONE
|
||||||
|
&& currentMode != ExoPlayer.REPEAT_MODE_OFF) {
|
||||||
|
controlDispatcher.dispatchSetRepeatMode(player, ExoPlayer.REPEAT_MODE_OFF);
|
||||||
|
} else if (repeatToggleModes == REPEAT_TOGGLE_MODE_ONE
|
||||||
|
&& currentMode == ExoPlayer.REPEAT_MODE_ALL) {
|
||||||
|
controlDispatcher.dispatchSetRepeatMode(player, ExoPlayer.REPEAT_MODE_ONE);
|
||||||
|
} else if (repeatToggleModes == REPEAT_TOGGLE_MODE_ALL
|
||||||
|
&& currentMode == ExoPlayer.REPEAT_MODE_ONE) {
|
||||||
|
controlDispatcher.dispatchSetRepeatMode(player, ExoPlayer.REPEAT_MODE_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the playback controls. If {@link #getShowTimeoutMs()} is positive then the controls will
|
* Shows the playback controls. If {@link #getShowTimeoutMs()} is positive then the controls will
|
||||||
* be automatically hidden after this duration of time has elapsed without user input.
|
* be automatically hidden after this duration of time has elapsed without user input.
|
||||||
@ -494,6 +610,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
private void updateAll() {
|
private void updateAll() {
|
||||||
updatePlayPauseButton();
|
updatePlayPauseButton();
|
||||||
updateNavigation();
|
updateNavigation();
|
||||||
|
updateRepeatModeButton();
|
||||||
updateProgress();
|
updateProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,6 +663,31 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateRepeatModeButton() {
|
||||||
|
if (!isVisible() || !isAttachedToWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (repeatToggleModes == REPEAT_TOGGLE_MODE_NONE) {
|
||||||
|
repeatToggleButton.setVisibility(View.GONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (player.getRepeatMode()) {
|
||||||
|
case ExoPlayer.REPEAT_MODE_OFF:
|
||||||
|
repeatToggleButton.setImageDrawable(repeatOffButtonDrawable);
|
||||||
|
repeatToggleButton.setContentDescription(repeatOffButtonContentDescription);
|
||||||
|
break;
|
||||||
|
case ExoPlayer.REPEAT_MODE_ONE:
|
||||||
|
repeatToggleButton.setImageDrawable(repeatOneButtonDrawable);
|
||||||
|
repeatToggleButton.setContentDescription(repeatOneButtonContentDescription);
|
||||||
|
break;
|
||||||
|
case ExoPlayer.REPEAT_MODE_ALL:
|
||||||
|
repeatToggleButton.setImageDrawable(repeatAllButtonDrawable);
|
||||||
|
repeatToggleButton.setContentDescription(repeatAllButtonContentDescription);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
repeatToggleButton.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateTimeBarMode() {
|
private void updateTimeBarMode() {
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return;
|
return;
|
||||||
@ -705,6 +847,30 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @ExoPlayer.RepeatMode int getNextRepeatMode() {
|
||||||
|
@ExoPlayer.RepeatMode int currentMode = player.getRepeatMode();
|
||||||
|
for (int offset = 1; offset <= 2; offset++) {
|
||||||
|
@ExoPlayer.RepeatMode int proposedMode = (currentMode + offset) % 3;
|
||||||
|
if (isRepeatModeEnabled(proposedMode)) {
|
||||||
|
return proposedMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRepeatModeEnabled(@ExoPlayer.RepeatMode int repeatMode) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case ExoPlayer.REPEAT_MODE_OFF:
|
||||||
|
return true;
|
||||||
|
case ExoPlayer.REPEAT_MODE_ONE:
|
||||||
|
return (repeatToggleModes & REPEAT_TOGGLE_MODE_ONE) != 0;
|
||||||
|
case ExoPlayer.REPEAT_MODE_ALL:
|
||||||
|
return (repeatToggleModes & REPEAT_TOGGLE_MODE_ALL) != 0;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void rewind() {
|
private void rewind() {
|
||||||
if (rewindMs <= 0) {
|
if (rewindMs <= 0) {
|
||||||
return;
|
return;
|
||||||
@ -908,7 +1074,8 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRepeatModeChanged(int repeatMode) {
|
public void onRepeatModeChanged(int repeatMode) {
|
||||||
// Do nothing.
|
updateRepeatModeButton();
|
||||||
|
updateNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -959,6 +1126,8 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
controlDispatcher.dispatchSetPlayWhenReady(player, true);
|
controlDispatcher.dispatchSetPlayWhenReady(player, true);
|
||||||
} else if (pauseButton == view) {
|
} else if (pauseButton == view) {
|
||||||
controlDispatcher.dispatchSetPlayWhenReady(player, false);
|
controlDispatcher.dispatchSetPlayWhenReady(player, false);
|
||||||
|
} else if (repeatToggleButton == view) {
|
||||||
|
controlDispatcher.dispatchSetRepeatMode(player, getNextRepeatMode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hideAfterTimeout();
|
hideAfterTimeout();
|
||||||
|
@ -591,6 +591,16 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
controller.setFastForwardIncrementMs(fastForwardMs);
|
controller.setFastForwardIncrementMs(fastForwardMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which repeat toggle modes are enabled.
|
||||||
|
*
|
||||||
|
* @param repeatToggleModes A set of {@link PlaybackControlView.RepeatToggleModes}.
|
||||||
|
*/
|
||||||
|
public void setRepeatToggleModes(@PlaybackControlView.RepeatToggleModes int repeatToggleModes) {
|
||||||
|
Assertions.checkState(controller != null);
|
||||||
|
controller.setRepeatToggleModes(repeatToggleModes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the time bar should show all windows, as opposed to just the current one.
|
* Sets whether the time bar should show all windows, as opposed to just the current one.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
|
||||||
|
</vector>
|
@ -0,0 +1,23 @@
|
|||||||
|
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#4EFFFFFF"
|
||||||
|
android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
|
||||||
|
</vector>
|
@ -0,0 +1,23 @@
|
|||||||
|
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="32dp"
|
||||||
|
android:width="32dp"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
|
android:viewportWidth="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4zM13,15L13,9h-1l-2,1v1h1.5v4L13,15z"/>
|
||||||
|
</vector>
|
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 166 B |
After Width: | Height: | Size: 160 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 227 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 288 B |
After Width: | Height: | Size: 322 B |
After Width: | Height: | Size: 331 B |
After Width: | Height: | Size: 266 B |
After Width: | Height: | Size: 309 B |
After Width: | Height: | Size: 309 B |
@ -34,6 +34,9 @@
|
|||||||
<ImageButton android:id="@id/exo_rew"
|
<ImageButton android:id="@id/exo_rew"
|
||||||
style="@style/ExoMediaButton.Rewind"/>
|
style="@style/ExoMediaButton.Rewind"/>
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_repeat_toggle"
|
||||||
|
style="@style/ExoMediaButton"/>
|
||||||
|
|
||||||
<ImageButton android:id="@id/exo_play"
|
<ImageButton android:id="@id/exo_play"
|
||||||
style="@style/ExoMediaButton.Play"/>
|
style="@style/ExoMediaButton.Play"/>
|
||||||
|
|
||||||
|
@ -34,6 +34,11 @@
|
|||||||
<attr name="fastforward_increment" format="integer"/>
|
<attr name="fastforward_increment" format="integer"/>
|
||||||
<attr name="player_layout_id" format="reference"/>
|
<attr name="player_layout_id" format="reference"/>
|
||||||
<attr name="controller_layout_id" format="reference"/>
|
<attr name="controller_layout_id" format="reference"/>
|
||||||
|
<attr name="repeat_toggle_modes">
|
||||||
|
<flag name="none" value="0"/>
|
||||||
|
<flag name="one" value="1"/>
|
||||||
|
<flag name="all" value="2"/>
|
||||||
|
</attr>
|
||||||
|
|
||||||
<declare-styleable name="SimpleExoPlayerView">
|
<declare-styleable name="SimpleExoPlayerView">
|
||||||
<attr name="use_artwork" format="boolean"/>
|
<attr name="use_artwork" format="boolean"/>
|
||||||
@ -57,6 +62,7 @@
|
|||||||
<attr name="show_timeout"/>
|
<attr name="show_timeout"/>
|
||||||
<attr name="rewind_increment"/>
|
<attr name="rewind_increment"/>
|
||||||
<attr name="fastforward_increment"/>
|
<attr name="fastforward_increment"/>
|
||||||
|
<attr name="repeat_toggle_modes"/>
|
||||||
<attr name="controller_layout_id"/>
|
<attr name="controller_layout_id"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
<item name="exo_ffwd" type="id"/>
|
<item name="exo_ffwd" type="id"/>
|
||||||
<item name="exo_prev" type="id"/>
|
<item name="exo_prev" type="id"/>
|
||||||
<item name="exo_next" type="id"/>
|
<item name="exo_next" type="id"/>
|
||||||
|
<item name="exo_repeat_toggle" type="id"/>
|
||||||
<item name="exo_duration" type="id"/>
|
<item name="exo_duration" type="id"/>
|
||||||
<item name="exo_position" type="id"/>
|
<item name="exo_position" type="id"/>
|
||||||
<item name="exo_progress" type="id"/>
|
<item name="exo_progress" type="id"/>
|
||||||
|