Add option to hide Prev/Rwnd/Ffwd/Next buttons

Issue: #7410
PiperOrigin-RevId: 315480798
This commit is contained in:
olly 2020-06-09 15:36:28 +01:00 committed by Ian Baker
parent a11f7b8cdd
commit c759b5b1a9
4 changed files with 147 additions and 18 deletions

View File

@ -184,6 +184,9 @@
* UI * UI
* Remove deperecated `exo_simple_player_view.xml` and * Remove deperecated `exo_simple_player_view.xml` and
`exo_playback_control_view.xml` from resource. `exo_playback_control_view.xml` from resource.
* Add setter methods to `PlayerView` and `PlayerControlView` to set
whether the rewind, fast forward, previous and next buttons are shown
([#7410](https://github.com/google/ExoPlayer/issues/7410)).
* Move logic of prev, next, fast forward and rewind to ControlDispatcher * Move logic of prev, next, fast forward and rewind to ControlDispatcher
([#6926](https://github.com/google/ExoPlayer/issues/6926)). ([#6926](https://github.com/google/ExoPlayer/issues/6926)).
* Update `TrackSelectionDialogBuilder` to use AndroidX Compat Dialog * Update `TrackSelectionDialogBuilder` to use AndroidX Compat Dialog
@ -211,10 +214,10 @@
([#7306](https://github.com/google/ExoPlayer/issues/7306)). ([#7306](https://github.com/google/ExoPlayer/issues/7306)).
* Fix issue in `AudioTrackPositionTracker` that could cause negative positions * Fix issue in `AudioTrackPositionTracker` that could cause negative positions
to be reported at the start of playback and immediately after seeking to be reported at the start of playback and immediately after seeking
([#7456](https://github.com/google/ExoPlayer/issues/7456). ([#7456](https://github.com/google/ExoPlayer/issues/7456)).
* Fix further cases where downloads would sometimes not resume after their * Fix further cases where downloads would sometimes not resume after their
network requirements are met network requirements are met
([#7453](https://github.com/google/ExoPlayer/issues/7453). ([#7453](https://github.com/google/ExoPlayer/issues/7453)).
* DASH: * DASH:
* Merge trick play adaptation sets (i.e., adaptation sets marked with * Merge trick play adaptation sets (i.e., adaptation sets marked with
`http://dashif.org/guidelines/trickmode`) into the same `TrackGroup` as `http://dashif.org/guidelines/trickmode`) into the same `TrackGroup` as
@ -295,11 +298,12 @@
to the `DefaultAudioSink` constructor to the `DefaultAudioSink` constructor
([#7134](https://github.com/google/ExoPlayer/issues/7134)). ([#7134](https://github.com/google/ExoPlayer/issues/7134)).
* Workaround issue that could cause slower than realtime playback of AAC * Workaround issue that could cause slower than realtime playback of AAC
on Android 10 ([#6671](https://github.com/google/ExoPlayer/issues/6671). on Android 10
([#6671](https://github.com/google/ExoPlayer/issues/6671)).
* Fix case where another app spuriously holding transient audio focus * Fix case where another app spuriously holding transient audio focus
could prevent ExoPlayer from acquiring audio focus for an indefinite could prevent ExoPlayer from acquiring audio focus for an indefinite
period of time period of time
([#7182](https://github.com/google/ExoPlayer/issues/7182). ([#7182](https://github.com/google/ExoPlayer/issues/7182)).
* Fix case where the player volume could be permanently ducked if audio * Fix case where the player volume could be permanently ducked if audio
focus was released whilst ducking. focus was released whilst ducking.
* Fix playback of WAV files with trailing non-media bytes * Fix playback of WAV files with trailing non-media bytes
@ -1248,7 +1252,7 @@
([#4492](https://github.com/google/ExoPlayer/issues/4492) and ([#4492](https://github.com/google/ExoPlayer/issues/4492) and
[#4634](https://github.com/google/ExoPlayer/issues/4634)). [#4634](https://github.com/google/ExoPlayer/issues/4634)).
* Fix issue where removing looping media from a playlist throws an exception * Fix issue where removing looping media from a playlist throws an exception
([#4871](https://github.com/google/ExoPlayer/issues/4871). ([#4871](https://github.com/google/ExoPlayer/issues/4871)).
* Fix issue where the preferred audio or text track would not be selected if * Fix issue where the preferred audio or text track would not be selected if
mapped onto a secondary renderer of the corresponding type mapped onto a secondary renderer of the corresponding type
([#4711](http://github.com/google/ExoPlayer/issues/4711)). ([#4711](http://github.com/google/ExoPlayer/issues/4711)).
@ -1679,7 +1683,7 @@
resources when the playback thread has quit by the time the loading task has resources when the playback thread has quit by the time the loading task has
completed. completed.
* ID3: Better handle malformed ID3 data * ID3: Better handle malformed ID3 data
([#3792](https://github.com/google/ExoPlayer/issues/3792). ([#3792](https://github.com/google/ExoPlayer/issues/3792)).
* Support 14-bit mode and little endianness in DTS PES packets * Support 14-bit mode and little endianness in DTS PES packets
([#3340](https://github.com/google/ExoPlayer/issues/3340)). ([#3340](https://github.com/google/ExoPlayer/issues/3340)).
* Demo app: Add ability to download not DRM protected content. * Demo app: Add ability to download not DRM protected content.

View File

@ -66,6 +66,26 @@ import java.util.concurrent.CopyOnWriteArrayList;
* <li>Corresponding method: {@link #setShowTimeoutMs(int)} * <li>Corresponding method: {@link #setShowTimeoutMs(int)}
* <li>Default: {@link #DEFAULT_SHOW_TIMEOUT_MS} * <li>Default: {@link #DEFAULT_SHOW_TIMEOUT_MS}
* </ul> * </ul>
* <li><b>{@code show_rewind_button}</b> - Whether the rewind button is shown.
* <ul>
* <li>Corresponding method: {@link #setShowRewindButton(boolean)}
* <li>Default: true
* </ul>
* <li><b>{@code show_fastforward_button}</b> - Whether the fast forward button is shown.
* <ul>
* <li>Corresponding method: {@link #setShowFastForwardButton(boolean)}
* <li>Default: true
* </ul>
* <li><b>{@code show_previous_button}</b> - Whether the previous button is shown.
* <ul>
* <li>Corresponding method: {@link #setShowPreviousButton(boolean)}
* <li>Default: true
* </ul>
* <li><b>{@code show_next_button}</b> - Whether the next button is shown.
* <ul>
* <li>Corresponding method: {@link #setShowNextButton(boolean)}
* <li>Default: true
* </ul>
* <li><b>{@code rewind_increment}</b> - The duration of the rewind applied when the user taps the * <li><b>{@code rewind_increment}</b> - The duration of the rewind applied when the user taps the
* rewind button, in milliseconds. Use zero to disable the rewind button. * rewind button, in milliseconds. Use zero to disable the rewind button.
* <ul> * <ul>
@ -305,6 +325,10 @@ public class PlayerControlView extends FrameLayout {
private int showTimeoutMs; private int showTimeoutMs;
private int timeBarMinUpdateIntervalMs; private int timeBarMinUpdateIntervalMs;
private @RepeatModeUtil.RepeatToggleModes int repeatToggleModes; private @RepeatModeUtil.RepeatToggleModes int repeatToggleModes;
private boolean showRewindButton;
private boolean showFastForwardButton;
private boolean showPreviousButton;
private boolean showNextButton;
private boolean showShuffleButton; private boolean showShuffleButton;
private long hideAtMs; private long hideAtMs;
private long[] adGroupTimesMs; private long[] adGroupTimesMs;
@ -341,6 +365,10 @@ public class PlayerControlView extends FrameLayout {
repeatToggleModes = DEFAULT_REPEAT_TOGGLE_MODES; repeatToggleModes = DEFAULT_REPEAT_TOGGLE_MODES;
timeBarMinUpdateIntervalMs = DEFAULT_TIME_BAR_MIN_UPDATE_INTERVAL_MS; timeBarMinUpdateIntervalMs = DEFAULT_TIME_BAR_MIN_UPDATE_INTERVAL_MS;
hideAtMs = C.TIME_UNSET; hideAtMs = C.TIME_UNSET;
showRewindButton = true;
showFastForwardButton = true;
showPreviousButton = true;
showNextButton = true;
showShuffleButton = false; showShuffleButton = false;
int rewindMs = DefaultControlDispatcher.DEFAULT_REWIND_MS; int rewindMs = DefaultControlDispatcher.DEFAULT_REWIND_MS;
int fastForwardMs = DefaultControlDispatcher.DEFAULT_FAST_FORWARD_MS; int fastForwardMs = DefaultControlDispatcher.DEFAULT_FAST_FORWARD_MS;
@ -357,6 +385,15 @@ public class PlayerControlView extends FrameLayout {
controllerLayoutId = controllerLayoutId =
a.getResourceId(R.styleable.PlayerControlView_controller_layout_id, controllerLayoutId); a.getResourceId(R.styleable.PlayerControlView_controller_layout_id, controllerLayoutId);
repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes); repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes);
showRewindButton =
a.getBoolean(R.styleable.PlayerControlView_show_rewind_button, showRewindButton);
showFastForwardButton =
a.getBoolean(
R.styleable.PlayerControlView_show_fastforward_button, showFastForwardButton);
showPreviousButton =
a.getBoolean(R.styleable.PlayerControlView_show_previous_button, showPreviousButton);
showNextButton =
a.getBoolean(R.styleable.PlayerControlView_show_next_button, showNextButton);
showShuffleButton = showShuffleButton =
a.getBoolean(R.styleable.PlayerControlView_show_shuffle_button, showShuffleButton); a.getBoolean(R.styleable.PlayerControlView_show_shuffle_button, showShuffleButton);
setTimeBarMinUpdateInterval( setTimeBarMinUpdateInterval(
@ -592,6 +629,46 @@ public class PlayerControlView extends FrameLayout {
} }
} }
/**
* Sets whether the rewind button is shown.
*
* @param showRewindButton Whether the rewind button is shown.
*/
public void setShowRewindButton(boolean showRewindButton) {
this.showRewindButton = showRewindButton;
updateNavigation();
}
/**
* Sets whether the fast forward button is shown.
*
* @param showFastForwardButton Whether the fast forward button is shown.
*/
public void setShowFastForwardButton(boolean showFastForwardButton) {
this.showFastForwardButton = showFastForwardButton;
updateNavigation();
}
/**
* Sets whether the previous button is shown.
*
* @param showPreviousButton Whether the previous button is shown.
*/
public void setShowPreviousButton(boolean showPreviousButton) {
this.showPreviousButton = showPreviousButton;
updateNavigation();
}
/**
* Sets whether the next button is shown.
*
* @param showNextButton Whether the next button is shown.
*/
public void setShowNextButton(boolean showNextButton) {
this.showNextButton = showNextButton;
updateNavigation();
}
/** /**
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} with {@link * @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} with {@link
* DefaultControlDispatcher#DefaultControlDispatcher(long, long)}. * DefaultControlDispatcher#DefaultControlDispatcher(long, long)}.
@ -832,10 +909,10 @@ public class PlayerControlView extends FrameLayout {
} }
} }
setButtonEnabled(enablePrevious, previousButton); updateButton(showPreviousButton, enablePrevious, previousButton);
setButtonEnabled(enableRewind, rewindButton); updateButton(showRewindButton, enableRewind, rewindButton);
setButtonEnabled(enableFastForward, fastForwardButton); updateButton(showFastForwardButton, enableFastForward, fastForwardButton);
setButtonEnabled(enableNext, nextButton); updateButton(showNextButton, enableNext, nextButton);
if (timeBar != null) { if (timeBar != null) {
timeBar.setEnabled(enableSeeking); timeBar.setEnabled(enableSeeking);
} }
@ -847,19 +924,19 @@ public class PlayerControlView extends FrameLayout {
} }
if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) { if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE) {
repeatToggleButton.setVisibility(GONE); updateButton(/* visible= */ false, /* enabled= */ false, repeatToggleButton);
return; return;
} }
@Nullable Player player = this.player; @Nullable Player player = this.player;
if (player == null) { if (player == null) {
setButtonEnabled(false, repeatToggleButton); updateButton(/* visible= */ true, /* enabled= */ false, repeatToggleButton);
repeatToggleButton.setImageDrawable(repeatOffButtonDrawable); repeatToggleButton.setImageDrawable(repeatOffButtonDrawable);
repeatToggleButton.setContentDescription(repeatOffButtonContentDescription); repeatToggleButton.setContentDescription(repeatOffButtonContentDescription);
return; return;
} }
setButtonEnabled(true, repeatToggleButton); updateButton(/* visible= */ true, /* enabled= */ true, repeatToggleButton);
switch (player.getRepeatMode()) { switch (player.getRepeatMode()) {
case Player.REPEAT_MODE_OFF: case Player.REPEAT_MODE_OFF:
repeatToggleButton.setImageDrawable(repeatOffButtonDrawable); repeatToggleButton.setImageDrawable(repeatOffButtonDrawable);
@ -886,13 +963,13 @@ public class PlayerControlView extends FrameLayout {
@Nullable Player player = this.player; @Nullable Player player = this.player;
if (!showShuffleButton) { if (!showShuffleButton) {
shuffleButton.setVisibility(GONE); updateButton(/* visible= */ false, /* enabled= */ false, shuffleButton);
} else if (player == null) { } else if (player == null) {
setButtonEnabled(false, shuffleButton); updateButton(/* visible= */ true, /* enabled= */ false, shuffleButton);
shuffleButton.setImageDrawable(shuffleOffButtonDrawable); shuffleButton.setImageDrawable(shuffleOffButtonDrawable);
shuffleButton.setContentDescription(shuffleOffContentDescription); shuffleButton.setContentDescription(shuffleOffContentDescription);
} else { } else {
setButtonEnabled(true, shuffleButton); updateButton(/* visible= */ true, /* enabled= */ true, shuffleButton);
shuffleButton.setImageDrawable( shuffleButton.setImageDrawable(
player.getShuffleModeEnabled() ? shuffleOnButtonDrawable : shuffleOffButtonDrawable); player.getShuffleModeEnabled() ? shuffleOnButtonDrawable : shuffleOffButtonDrawable);
shuffleButton.setContentDescription( shuffleButton.setContentDescription(
@ -1029,13 +1106,13 @@ public class PlayerControlView extends FrameLayout {
} }
} }
private void setButtonEnabled(boolean enabled, @Nullable View view) { private void updateButton(boolean visible, boolean enabled, @Nullable View view) {
if (view == null) { if (view == null) {
return; return;
} }
view.setEnabled(enabled); view.setEnabled(enabled);
view.setAlpha(enabled ? buttonAlphaEnabled : buttonAlphaDisabled); view.setAlpha(enabled ? buttonAlphaEnabled : buttonAlphaDisabled);
view.setVisibility(VISIBLE); view.setVisibility(visible ? VISIBLE : GONE);
} }
private void seekToTimeBarPosition(Player player, long positionMs) { private void seekToTimeBarPosition(Player player, long positionMs) {

View File

@ -1000,6 +1000,46 @@ public class PlayerView extends FrameLayout implements AdsLoader.AdViewProvider
controller.setControlDispatcher(controlDispatcher); controller.setControlDispatcher(controlDispatcher);
} }
/**
* Sets whether the rewind button is shown.
*
* @param showRewindButton Whether the rewind button is shown.
*/
public void setShowRewindButton(boolean showRewindButton) {
Assertions.checkStateNotNull(controller);
controller.setShowRewindButton(showRewindButton);
}
/**
* Sets whether the fast forward button is shown.
*
* @param showFastForwardButton Whether the fast forward button is shown.
*/
public void setShowFastForwardButton(boolean showFastForwardButton) {
Assertions.checkStateNotNull(controller);
controller.setShowFastForwardButton(showFastForwardButton);
}
/**
* Sets whether the previous button is shown.
*
* @param showPreviousButton Whether the previous button is shown.
*/
public void setShowPreviousButton(boolean showPreviousButton) {
Assertions.checkStateNotNull(controller);
controller.setShowPreviousButton(showPreviousButton);
}
/**
* Sets whether the next button is shown.
*
* @param showNextButton Whether the next button is shown.
*/
public void setShowNextButton(boolean showNextButton) {
Assertions.checkStateNotNull(controller);
controller.setShowNextButton(showNextButton);
}
/** /**
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} with {@link * @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} with {@link
* DefaultControlDispatcher#DefaultControlDispatcher(long, long)}. * DefaultControlDispatcher#DefaultControlDispatcher(long, long)}.

View File

@ -44,6 +44,10 @@
<attr name="show_timeout" format="integer"/> <attr name="show_timeout" format="integer"/>
<attr name="rewind_increment" format="integer"/> <attr name="rewind_increment" format="integer"/>
<attr name="fastforward_increment" format="integer"/> <attr name="fastforward_increment" format="integer"/>
<attr name="show_rewind_button" format="boolean"/>
<attr name="show_fastforward_button" format="boolean"/>
<attr name="show_previous_button" format="boolean"/>
<attr name="show_next_button" format="boolean"/>
<attr name="show_shuffle_button" format="boolean"/> <attr name="show_shuffle_button" format="boolean"/>
<attr name="time_bar_min_update_interval" format="integer"/> <attr name="time_bar_min_update_interval" format="integer"/>
<attr name="controller_layout_id" format="reference"/> <attr name="controller_layout_id" format="reference"/>
@ -115,6 +119,10 @@
<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_rewind_button"/>
<attr name="show_fastforward_button"/>
<attr name="show_previous_button"/>
<attr name="show_next_button"/>
<attr name="show_shuffle_button"/> <attr name="show_shuffle_button"/>
<attr name="time_bar_min_update_interval"/> <attr name="time_bar_min_update_interval"/>
<attr name="controller_layout_id"/> <attr name="controller_layout_id"/>