Add UI for shuffle mode.

This includes an option to show and hide the shuffle mode button. When
pressing the button, the shuffle mode of the player is toggled.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=166455759
This commit is contained in:
tonihei 2017-08-25 02:52:35 -07:00 committed by Oliver Woodman
parent 6907ffb285
commit 1b9c904dba
4 changed files with 87 additions and 1 deletions

View file

@ -84,6 +84,12 @@ import java.util.Locale;
* <li>Default: {@link PlaybackControlView#DEFAULT_REPEAT_TOGGLE_MODES}</li> * <li>Default: {@link PlaybackControlView#DEFAULT_REPEAT_TOGGLE_MODES}</li>
* </ul> * </ul>
* </li> * </li>
* <li><b>{@code show_shuffle_button}</b> - Whether the shuffle button is shown.
* <ul>
* <li>Corresponding method: {@link #setShowShuffleButton(boolean)}</li>
* <li>Default: false</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>
@ -136,6 +142,11 @@ import java.util.Locale;
* <li>Type: {@link View}</li> * <li>Type: {@link View}</li>
* </ul> * </ul>
* </li> * </li>
* <li><b>{@code exo_shuffle}</b> - The shuffle 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>
@ -221,6 +232,15 @@ public class PlaybackControlView extends FrameLayout {
*/ */
boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode); boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode);
/**
* Dispatches a {@link Player#setShuffleModeEnabled(boolean)} operation.
*
* @param player The {@link Player} to which the operation should be dispatched.
* @param shuffleModeEnabled Whether shuffling is enabled.
* @return True if the operation was dispatched. False if suppressed.
*/
boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled);
} }
/** /**
@ -247,6 +267,12 @@ public class PlaybackControlView extends FrameLayout {
return true; return true;
} }
@Override
public boolean dispatchSetShuffleModeEnabled(Player player, boolean shuffleModeEnabled) {
player.setShuffleModeEnabled(shuffleModeEnabled);
return true;
}
}; };
/** /**
@ -282,6 +308,7 @@ public class PlaybackControlView extends FrameLayout {
private final View fastForwardButton; private final View fastForwardButton;
private final View rewindButton; private final View rewindButton;
private final ImageView repeatToggleButton; private final ImageView repeatToggleButton;
private final View shuffleButton;
private final TextView durationView; private final TextView durationView;
private final TextView positionView; private final TextView positionView;
private final TimeBar timeBar; private final TimeBar timeBar;
@ -309,6 +336,7 @@ public class PlaybackControlView extends FrameLayout {
private int fastForwardMs; private int fastForwardMs;
private int showTimeoutMs; private int showTimeoutMs;
private @RepeatModeUtil.RepeatToggleModes int repeatToggleModes; private @RepeatModeUtil.RepeatToggleModes int repeatToggleModes;
private boolean showShuffleButton;
private long hideAtMs; private long hideAtMs;
private long[] adGroupTimesMs; private long[] adGroupTimesMs;
private boolean[] playedAdGroups; private boolean[] playedAdGroups;
@ -345,6 +373,7 @@ public class PlaybackControlView extends FrameLayout {
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; repeatToggleModes = DEFAULT_REPEAT_TOGGLE_MODES;
showShuffleButton = false;
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);
@ -356,6 +385,8 @@ public class PlaybackControlView extends FrameLayout {
controllerLayoutId = a.getResourceId(R.styleable.PlaybackControlView_controller_layout_id, controllerLayoutId = a.getResourceId(R.styleable.PlaybackControlView_controller_layout_id,
controllerLayoutId); controllerLayoutId);
repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes); repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes);
showShuffleButton = a.getBoolean(R.styleable.PlaybackControlView_show_shuffle_button,
showShuffleButton);
} finally { } finally {
a.recycle(); a.recycle();
} }
@ -408,6 +439,10 @@ public class PlaybackControlView extends FrameLayout {
if (repeatToggleButton != null) { if (repeatToggleButton != null) {
repeatToggleButton.setOnClickListener(componentListener); repeatToggleButton.setOnClickListener(componentListener);
} }
shuffleButton = findViewById(R.id.exo_shuffle);
if (shuffleButton != null) {
shuffleButton.setOnClickListener(componentListener);
}
Resources resources = context.getResources(); Resources resources = context.getResources();
repeatOffButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_off); repeatOffButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_off);
repeatOneButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_one); repeatOneButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_one);
@ -584,6 +619,23 @@ public class PlaybackControlView extends FrameLayout {
} }
} }
/**
* Returns whether the shuffle button is shown.
*/
public boolean getShowShuffleButton() {
return showShuffleButton;
}
/**
* Sets whether the shuffle button is shown.
*
* @param showShuffleButton Whether the shuffle button is shown.
*/
public void setShowShuffleButton(boolean showShuffleButton) {
this.showShuffleButton = showShuffleButton;
updateShuffleButton();
}
/** /**
* 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.
@ -639,6 +691,7 @@ public class PlaybackControlView extends FrameLayout {
updatePlayPauseButton(); updatePlayPauseButton();
updateNavigation(); updateNavigation();
updateRepeatModeButton(); updateRepeatModeButton();
updateShuffleButton();
updateProgress(); updateProgress();
} }
@ -721,6 +774,21 @@ public class PlaybackControlView extends FrameLayout {
repeatToggleButton.setVisibility(View.VISIBLE); repeatToggleButton.setVisibility(View.VISIBLE);
} }
private void updateShuffleButton() {
if (!isVisible() || !isAttachedToWindow || shuffleButton == null) {
return;
}
if (!showShuffleButton) {
shuffleButton.setVisibility(View.GONE);
} else if (player == null) {
setButtonEnabled(false, shuffleButton);
} else {
shuffleButton.setAlpha(player.getShuffleModeEnabled() ? 1f : 0.3f);
shuffleButton.setEnabled(true);
shuffleButton.setVisibility(View.VISIBLE);
}
}
private void updateTimeBarMode() { private void updateTimeBarMode() {
if (player == null) { if (player == null) {
return; return;
@ -1080,7 +1148,8 @@ public class PlaybackControlView extends FrameLayout {
@Override @Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
// TODO: Update UI. updateShuffleButton();
updateNavigation();
} }
@Override @Override
@ -1134,6 +1203,8 @@ public class PlaybackControlView extends FrameLayout {
} else if (repeatToggleButton == view) { } else if (repeatToggleButton == view) {
controlDispatcher.dispatchSetRepeatMode(player, RepeatModeUtil.getNextRepeatMode( controlDispatcher.dispatchSetRepeatMode(player, RepeatModeUtil.getNextRepeatMode(
player.getRepeatMode(), repeatToggleModes)); player.getRepeatMode(), repeatToggleModes));
} else if (shuffleButton == view) {
controlDispatcher.dispatchSetShuffleModeEnabled(player, !player.getShuffleModeEnabled());
} }
} }
hideAfterTimeout(); hideAfterTimeout();

View file

@ -655,6 +655,16 @@ public final class SimpleExoPlayerView extends FrameLayout {
controller.setRepeatToggleModes(repeatToggleModes); controller.setRepeatToggleModes(repeatToggleModes);
} }
/**
* Sets whether the shuffle button is shown.
*
* @param showShuffleButton Whether the shuffle button is shown.
*/
public void setShowShuffleButton(boolean showShuffleButton) {
Assertions.checkState(controller != null);
controller.setShowShuffleButton(showShuffleButton);
}
/** /**
* 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.
* *

View file

@ -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_shuffle"
style="@style/ExoMediaButton.Shuffle"/>
<ImageButton android:id="@id/exo_repeat_toggle" <ImageButton android:id="@id/exo_repeat_toggle"
style="@style/ExoMediaButton"/> style="@style/ExoMediaButton"/>

View file

@ -39,6 +39,7 @@
<flag name="one" value="1"/> <flag name="one" value="1"/>
<flag name="all" value="2"/> <flag name="all" value="2"/>
</attr> </attr>
<attr name="show_shuffle_button" format="boolean"/>
<declare-styleable name="SimpleExoPlayerView"> <declare-styleable name="SimpleExoPlayerView">
<attr name="use_artwork" format="boolean"/> <attr name="use_artwork" format="boolean"/>
@ -64,6 +65,7 @@
<attr name="rewind_increment"/> <attr name="rewind_increment"/>
<attr name="fastforward_increment"/> <attr name="fastforward_increment"/>
<attr name="repeat_toggle_modes"/> <attr name="repeat_toggle_modes"/>
<attr name="show_shuffle_button"/>
<attr name="controller_layout_id"/> <attr name="controller_layout_id"/>
</declare-styleable> </declare-styleable>