Reformat UI classes

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=180777553
This commit is contained in:
olly 2018-01-04 03:13:32 -08:00 committed by Oliver Woodman
parent 8e8e53c42d
commit a314db04ad
2 changed files with 175 additions and 205 deletions

View file

@ -42,127 +42,118 @@ import java.util.Locale;
/** /**
* A view for controlling {@link Player} instances. * A view for controlling {@link Player} instances.
* <p> *
* A PlaybackControlView can be customized by setting attributes (or calling corresponding methods), * <p>A PlaybackControlView can be customized by setting attributes (or calling corresponding
* overriding the view's layout file or by specifying a custom view layout file, as outlined below. * methods), overriding the view's layout file or by specifying a custom view layout file, as
* outlined below.
* *
* <h3>Attributes</h3> * <h3>Attributes</h3>
*
* The following attributes can be set on a PlaybackControlView when used in a layout XML file: * The following attributes can be set on a PlaybackControlView when used in a layout XML file:
*
* <p> * <p>
*
* <ul> * <ul>
* <li><b>{@code show_timeout}</b> - The time between the last user interaction and the controls * <li><b>{@code show_timeout}</b> - The time between the last user interaction and the controls
* being automatically hidden, in milliseconds. Use zero if the controls should not * being automatically hidden, in milliseconds. Use zero if the controls should not
* automatically timeout. * automatically timeout.
* <ul> * <ul>
* <li>Corresponding method: {@link #setShowTimeoutMs(int)}</li> * <li>Corresponding method: {@link #setShowTimeoutMs(int)}
* <li>Default: {@link #DEFAULT_SHOW_TIMEOUT_MS}</li> * <li>Default: {@link #DEFAULT_SHOW_TIMEOUT_MS}
* </ul> * </ul>
* </li>
* <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>
* <li>Corresponding method: {@link #setRewindIncrementMs(int)}</li> * <li>Corresponding method: {@link #setRewindIncrementMs(int)}
* <li>Default: {@link #DEFAULT_REWIND_MS}</li> * <li>Default: {@link #DEFAULT_REWIND_MS}
* </ul> * </ul>
* </li>
* <li><b>{@code fastforward_increment}</b> - Like {@code rewind_increment}, but for fast forward. * <li><b>{@code fastforward_increment}</b> - Like {@code rewind_increment}, but for fast forward.
* <ul> * <ul>
* <li>Corresponding method: {@link #setFastForwardIncrementMs(int)}</li> * <li>Corresponding method: {@link #setFastForwardIncrementMs(int)}
* <li>Default: {@link #DEFAULT_FAST_FORWARD_MS}</li> * <li>Default: {@link #DEFAULT_FAST_FORWARD_MS}
* </ul> * </ul>
* </li>
* <li><b>{@code repeat_toggle_modes}</b> - A flagged enumeration value specifying which repeat * <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}, * mode toggle options are enabled. Valid values are: {@code none}, {@code one}, {@code all},
* {@code all}, or {@code one|all}. * or {@code one|all}.
* <ul> * <ul>
* <li>Corresponding method: {@link #setRepeatToggleModes(int)}</li> * <li>Corresponding method: {@link #setRepeatToggleModes(int)}
* <li>Default: {@link PlaybackControlView#DEFAULT_REPEAT_TOGGLE_MODES}</li> * <li>Default: {@link PlaybackControlView#DEFAULT_REPEAT_TOGGLE_MODES}
* </ul> * </ul>
* </li>
* <li><b>{@code show_shuffle_button}</b> - Whether the shuffle button is shown. * <li><b>{@code show_shuffle_button}</b> - Whether the shuffle button is shown.
* <ul> * <ul>
* <li>Corresponding method: {@link #setShowShuffleButton(boolean)}</li> * <li>Corresponding method: {@link #setShowShuffleButton(boolean)}
* <li>Default: false</li> * <li>Default: false
* </ul> * </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>
* <li>Corresponding method: None</li> * <li>Corresponding method: None
* <li>Default: {@code R.id.exo_playback_control_view}</li> * <li>Default: {@code R.id.exo_playback_control_view}
* </ul> * </ul>
* </li>
* </ul> * </ul>
* *
* <h3>Overriding the layout file</h3> * <h3>Overriding the layout file</h3>
*
* To customize the layout of PlaybackControlView throughout your app, or just for certain * To customize the layout of PlaybackControlView throughout your app, or just for certain
* configurations, you can define {@code exo_playback_control_view.xml} layout files in your * configurations, you can define {@code exo_playback_control_view.xml} layout files in your
* application {@code res/layout*} directories. These layouts will override the one provided by the * application {@code res/layout*} directories. These layouts will override the one provided by the
* ExoPlayer library, and will be inflated for use by PlaybackControlView. The view identifies and * ExoPlayer library, and will be inflated for use by PlaybackControlView. The view identifies and
* binds its children by looking for the following ids: * binds its children by looking for the following ids:
*
* <p> * <p>
*
* <ul> * <ul>
* <li><b>{@code exo_play}</b> - The play button. * <li><b>{@code exo_play}</b> - The play button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_pause}</b> - The pause button. * <li><b>{@code exo_pause}</b> - The pause button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_ffwd}</b> - The fast forward button. * <li><b>{@code exo_ffwd}</b> - The fast forward button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_rew}</b> - The rewind button. * <li><b>{@code exo_rew}</b> - The rewind button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_prev}</b> - The previous track button. * <li><b>{@code exo_prev}</b> - The previous track button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_next}</b> - The next track button. * <li><b>{@code exo_next}</b> - The next track button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_repeat_toggle}</b> - The repeat toggle button. * <li><b>{@code exo_repeat_toggle}</b> - The repeat toggle button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_shuffle}</b> - The shuffle button. * <li><b>{@code exo_shuffle}</b> - The shuffle button.
* <ul> * <ul>
* <li>Type: {@link View}</li> * <li>Type: {@link View}
* </ul> * </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}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_duration}</b> - Text view displaying the current media duration. * <li><b>{@code exo_duration}</b> - Text view displaying the current media duration.
* <ul> * <ul>
* <li>Type: {@link TextView}</li> * <li>Type: {@link TextView}
* </ul> * </ul>
* </li>
* <li><b>{@code exo_progress}</b> - Time bar that's updated during playback and allows seeking. * <li><b>{@code exo_progress}</b> - Time bar that's updated during playback and allows seeking.
* <ul> * <ul>
* <li>Type: {@link TimeBar}</li> * <li>Type: {@link TimeBar}
* </ul> * </ul>
* </li>
* </ul> * </ul>
* <p> *
* All child views are optional and so can be omitted if not required, however where defined they * <p>All child views are optional and so can be omitted if not required, however where defined they
* must be of the expected type. * must be of the expected type.
* *
* <h3>Specifying a custom layout file</h3> * <h3>Specifying a custom layout file</h3>
*
* Defining your own {@code exo_playback_control_view.xml} is useful to customize the layout of * Defining your own {@code exo_playback_control_view.xml} is useful to customize the layout of
* PlaybackControlView throughout your application. It's also possible to customize the layout for a * PlaybackControlView throughout your application. It's also possible to customize the layout for a
* single instance in a layout file. This is achieved by setting the {@code controller_layout_id} * single instance in a layout file. This is achieved by setting the {@code controller_layout_id}
@ -175,15 +166,11 @@ public class PlaybackControlView extends FrameLayout {
ExoPlayerLibraryInfo.registerModule("goog.exo.ui"); ExoPlayerLibraryInfo.registerModule("goog.exo.ui");
} }
/** /** @deprecated Use {@link com.google.android.exoplayer2.ControlDispatcher}. */
* @deprecated Use {@link com.google.android.exoplayer2.ControlDispatcher}.
*/
@Deprecated @Deprecated
public interface ControlDispatcher extends com.google.android.exoplayer2.ControlDispatcher {} public interface ControlDispatcher extends com.google.android.exoplayer2.ControlDispatcher {}
/** /** Listener to be notified about changes of the visibility of the UI control. */
* Listener to be notified about changes of the visibility of the UI control.
*/
public interface VisibilityListener { public interface VisibilityListener {
/** /**
@ -192,38 +179,25 @@ public class PlaybackControlView extends FrameLayout {
* @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}. * @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}.
*/ */
void onVisibilityChange(int visibility); void onVisibilityChange(int visibility);
} }
private static final class DefaultControlDispatcher private static final class DefaultControlDispatcher
extends com.google.android.exoplayer2.DefaultControlDispatcher implements ControlDispatcher {} extends com.google.android.exoplayer2.DefaultControlDispatcher implements ControlDispatcher {}
/** /** @deprecated Use {@link com.google.android.exoplayer2.DefaultControlDispatcher}. */
* @deprecated Use {@link com.google.android.exoplayer2.DefaultControlDispatcher}.
*/
@Deprecated @Deprecated
public static final ControlDispatcher DEFAULT_CONTROL_DISPATCHER = new DefaultControlDispatcher(); public static final ControlDispatcher DEFAULT_CONTROL_DISPATCHER = new DefaultControlDispatcher();
/** /** The default fast forward increment, in milliseconds. */
* The default fast forward increment, in milliseconds.
*/
public static final int DEFAULT_FAST_FORWARD_MS = 15000; public static final int DEFAULT_FAST_FORWARD_MS = 15000;
/** /** The default rewind increment, in milliseconds. */
* The default rewind increment, in milliseconds.
*/
public static final int DEFAULT_REWIND_MS = 5000; public static final int DEFAULT_REWIND_MS = 5000;
/** /** The default show timeout, in milliseconds. */
* The default show timeout, in milliseconds.
*/
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000; public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
/** /** The default repeat toggle modes. */
* The default repeat toggle modes.
*/
public static final @RepeatModeUtil.RepeatToggleModes int DEFAULT_REPEAT_TOGGLE_MODES = public static final @RepeatModeUtil.RepeatToggleModes int DEFAULT_REPEAT_TOGGLE_MODES =
RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE; RepeatModeUtil.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.
*/
public static final int MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR = 100; public static final int MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR = 100;
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000; private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000;
@ -271,14 +245,16 @@ public class PlaybackControlView extends FrameLayout {
private long[] extraAdGroupTimesMs; private long[] extraAdGroupTimesMs;
private boolean[] extraPlayedAdGroups; private boolean[] extraPlayedAdGroups;
private final Runnable updateProgressAction = new Runnable() { private final Runnable updateProgressAction =
new Runnable() {
@Override @Override
public void run() { public void run() {
updateProgress(); updateProgress();
} }
}; };
private final Runnable hideAction = new Runnable() { private final Runnable hideAction =
new Runnable() {
@Override @Override
public void run() { public void run() {
hide(); hide();
@ -297,8 +273,8 @@ public class PlaybackControlView extends FrameLayout {
this(context, attrs, defStyleAttr, attrs); this(context, attrs, defStyleAttr, attrs);
} }
public PlaybackControlView(Context context, AttributeSet attrs, int defStyleAttr, public PlaybackControlView(
AttributeSet playbackAttrs) { Context context, AttributeSet attrs, int defStyleAttr, AttributeSet playbackAttrs) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
int controllerLayoutId = R.layout.exo_playback_control_view; int controllerLayoutId = R.layout.exo_playback_control_view;
rewindMs = DEFAULT_REWIND_MS; rewindMs = DEFAULT_REWIND_MS;
@ -307,18 +283,21 @@ public class PlaybackControlView extends FrameLayout {
repeatToggleModes = DEFAULT_REPEAT_TOGGLE_MODES; repeatToggleModes = DEFAULT_REPEAT_TOGGLE_MODES;
showShuffleButton = false; showShuffleButton = false;
if (playbackAttrs != null) { if (playbackAttrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(playbackAttrs, TypedArray a =
R.styleable.PlaybackControlView, 0, 0); context
.getTheme()
.obtainStyledAttributes(playbackAttrs, R.styleable.PlaybackControlView, 0, 0);
try { try {
rewindMs = a.getInt(R.styleable.PlaybackControlView_rewind_increment, rewindMs); rewindMs = a.getInt(R.styleable.PlaybackControlView_rewind_increment, rewindMs);
fastForwardMs = a.getInt(R.styleable.PlaybackControlView_fastforward_increment, fastForwardMs =
fastForwardMs); a.getInt(R.styleable.PlaybackControlView_fastforward_increment, fastForwardMs);
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 =
controllerLayoutId); a.getResourceId(
R.styleable.PlaybackControlView_controller_layout_id, controllerLayoutId);
repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes); repeatToggleModes = getRepeatToggleModes(a, repeatToggleModes);
showShuffleButton = a.getBoolean(R.styleable.PlaybackControlView_show_shuffle_button, showShuffleButton =
showShuffleButton); a.getBoolean(R.styleable.PlaybackControlView_show_shuffle_button, showShuffleButton);
} finally { } finally {
a.recycle(); a.recycle();
} }
@ -379,17 +358,17 @@ public class PlaybackControlView extends FrameLayout {
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);
repeatAllButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_all); repeatAllButtonDrawable = resources.getDrawable(R.drawable.exo_controls_repeat_all);
repeatOffButtonContentDescription = resources.getString( repeatOffButtonContentDescription =
R.string.exo_controls_repeat_off_description); resources.getString(R.string.exo_controls_repeat_off_description);
repeatOneButtonContentDescription = resources.getString( repeatOneButtonContentDescription =
R.string.exo_controls_repeat_one_description); resources.getString(R.string.exo_controls_repeat_one_description);
repeatAllButtonContentDescription = resources.getString( repeatAllButtonContentDescription =
R.string.exo_controls_repeat_all_description); resources.getString(R.string.exo_controls_repeat_all_description);
} }
@SuppressWarnings("ResourceType") @SuppressWarnings("ResourceType")
private static @RepeatModeUtil.RepeatToggleModes int getRepeatToggleModes(TypedArray a, private static @RepeatModeUtil.RepeatToggleModes int getRepeatToggleModes(
@RepeatModeUtil.RepeatToggleModes int repeatToggleModes) { TypedArray a, @RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
return a.getInt(R.styleable.PlaybackControlView_repeat_toggle_modes, repeatToggleModes); return a.getInt(R.styleable.PlaybackControlView_repeat_toggle_modes, repeatToggleModes);
} }
@ -422,9 +401,9 @@ public class PlaybackControlView extends FrameLayout {
/** /**
* Sets whether the time bar should show all windows, as opposed to just the current one. If the * Sets whether the time bar should show all windows, as opposed to just the current one. If the
* timeline has a period with unknown duration or more than * timeline has a period with unknown duration or more than {@link
* {@link #MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR} windows the time bar will fall back to showing a * #MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR} windows the time bar will fall back to showing a single
* single window. * window.
* *
* @param showMultiWindowTimeBar Whether the time bar should show all windows. * @param showMultiWindowTimeBar Whether the time bar should show all windows.
*/ */
@ -443,8 +422,8 @@ public class PlaybackControlView extends FrameLayout {
* @param extraPlayedAdGroups Whether each ad has been played, or {@code null} to show no extra ad * @param extraPlayedAdGroups Whether each ad has been played, or {@code null} to show no extra ad
* markers. * markers.
*/ */
public void setExtraAdGroupMarkers(@Nullable long[] extraAdGroupTimesMs, public void setExtraAdGroupMarkers(
@Nullable boolean[] extraPlayedAdGroups) { @Nullable long[] extraAdGroupTimesMs, @Nullable boolean[] extraPlayedAdGroups) {
if (extraAdGroupTimesMs == null) { if (extraAdGroupTimesMs == null) {
this.extraAdGroupTimesMs = new long[0]; this.extraAdGroupTimesMs = new long[0];
this.extraPlayedAdGroups = new boolean[0]; this.extraPlayedAdGroups = new boolean[0];
@ -473,8 +452,10 @@ public class PlaybackControlView extends FrameLayout {
*/ */
public void setControlDispatcher( public void setControlDispatcher(
@Nullable com.google.android.exoplayer2.ControlDispatcher controlDispatcher) { @Nullable com.google.android.exoplayer2.ControlDispatcher controlDispatcher) {
this.controlDispatcher = controlDispatcher == null this.controlDispatcher =
? new com.google.android.exoplayer2.DefaultControlDispatcher() : controlDispatcher; controlDispatcher == null
? new com.google.android.exoplayer2.DefaultControlDispatcher()
: controlDispatcher;
} }
/** /**
@ -556,9 +537,7 @@ public class PlaybackControlView extends FrameLayout {
} }
} }
/** /** Returns whether the shuffle button is shown. */
* Returns whether the shuffle button is shown.
*/
public boolean getShowShuffleButton() { public boolean getShowShuffleButton() {
return showShuffleButton; return showShuffleButton;
} }
@ -590,9 +569,7 @@ public class PlaybackControlView extends FrameLayout {
hideAfterTimeout(); hideAfterTimeout();
} }
/** /** Hides the controller. */
* Hides the controller.
*/
public void hide() { public void hide() {
if (isVisible()) { if (isVisible()) {
setVisibility(GONE); setVisibility(GONE);
@ -605,9 +582,7 @@ public class PlaybackControlView extends FrameLayout {
} }
} }
/** /** Returns whether the controller is currently visible. */
* Returns whether the controller is currently visible.
*/
public boolean isVisible() { public boolean isVisible() {
return getVisibility() == VISIBLE; return getVisibility() == VISIBLE;
} }
@ -664,8 +639,8 @@ public class PlaybackControlView extends FrameLayout {
int windowIndex = player.getCurrentWindowIndex(); int windowIndex = player.getCurrentWindowIndex();
timeline.getWindow(windowIndex, window); timeline.getWindow(windowIndex, window);
isSeekable = window.isSeekable; isSeekable = window.isSeekable;
enablePrevious = isSeekable || !window.isDynamic enablePrevious =
|| player.getPreviousWindowIndex() != C.INDEX_UNSET; isSeekable || !window.isDynamic || player.getPreviousWindowIndex() != C.INDEX_UNSET;
enableNext = window.isDynamic || player.getNextWindowIndex() != C.INDEX_UNSET; enableNext = window.isDynamic || player.getNextWindowIndex() != C.INDEX_UNSET;
} }
setButtonEnabled(enablePrevious, previousButton); setButtonEnabled(enablePrevious, previousButton);
@ -728,8 +703,8 @@ public class PlaybackControlView extends FrameLayout {
if (player == null) { if (player == null) {
return; return;
} }
multiWindowTimeBar = showMultiWindowTimeBar multiWindowTimeBar =
&& canShowMultiWindowTimeBar(player.getCurrentTimeline(), window); showMultiWindowTimeBar && canShowMultiWindowTimeBar(player.getCurrentTimeline(), window);
} }
private void updateProgress() { private void updateProgress() {
@ -836,8 +811,8 @@ public class PlaybackControlView extends FrameLayout {
if (mediaTimeDelayMs < (mediaTimeUpdatePeriodMs / 5)) { if (mediaTimeDelayMs < (mediaTimeUpdatePeriodMs / 5)) {
mediaTimeDelayMs += mediaTimeUpdatePeriodMs; mediaTimeDelayMs += mediaTimeUpdatePeriodMs;
} }
delayMs = playbackSpeed == 1 ? mediaTimeDelayMs delayMs =
: (long) (mediaTimeDelayMs / playbackSpeed); playbackSpeed == 1 ? mediaTimeDelayMs : (long) (mediaTimeDelayMs / playbackSpeed);
} else { } else {
delayMs = 200; delayMs = 200;
} }
@ -1054,8 +1029,8 @@ public class PlaybackControlView extends FrameLayout {
return true; return true;
} }
private final class ComponentListener extends Player.DefaultEventListener implements private final class ComponentListener extends Player.DefaultEventListener
TimeBar.OnScrubListener, OnClickListener { implements TimeBar.OnScrubListener, OnClickListener {
@Override @Override
public void onScrubStart(TimeBar timeBar, long position) { public void onScrubStart(TimeBar timeBar, long position) {
@ -1104,8 +1079,8 @@ public class PlaybackControlView extends FrameLayout {
} }
@Override @Override
public void onTimelineChanged(Timeline timeline, Object manifest, public void onTimelineChanged(
@Player.TimelineChangeReason int reason) { Timeline timeline, Object manifest, @Player.TimelineChangeReason int reason) {
updateNavigation(); updateNavigation();
updateTimeBarMode(); updateTimeBarMode();
updateProgress(); updateProgress();
@ -1127,15 +1102,13 @@ public class PlaybackControlView extends FrameLayout {
} else if (pauseButton == view) { } else if (pauseButton == view) {
controlDispatcher.dispatchSetPlayWhenReady(player, false); controlDispatcher.dispatchSetPlayWhenReady(player, false);
} else if (repeatToggleButton == view) { } else if (repeatToggleButton == view) {
controlDispatcher.dispatchSetRepeatMode(player, RepeatModeUtil.getNextRepeatMode( controlDispatcher.dispatchSetRepeatMode(
player.getRepeatMode(), repeatToggleModes)); player, RepeatModeUtil.getNextRepeatMode(player.getRepeatMode(), repeatToggleModes));
} else if (shuffleButton == view) { } else if (shuffleButton == view) {
controlDispatcher.dispatchSetShuffleModeEnabled(player, !player.getShuffleModeEnabled()); controlDispatcher.dispatchSetShuffleModeEnabled(player, !player.getShuffleModeEnabled());
} }
} }
hideAfterTimeout(); hideAfterTimeout();
} }
} }
} }

View file

@ -268,26 +268,26 @@ public final class SimpleExoPlayerView extends FrameLayout {
boolean controllerAutoShow = true; boolean controllerAutoShow = true;
boolean controllerHideDuringAds = true; boolean controllerHideDuringAds = true;
if (attrs != null) { if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, TypedArray a =
R.styleable.SimpleExoPlayerView, 0, 0); context.getTheme().obtainStyledAttributes(attrs, R.styleable.SimpleExoPlayerView, 0, 0);
try { try {
shutterColorSet = a.hasValue(R.styleable.SimpleExoPlayerView_shutter_background_color); shutterColorSet = a.hasValue(R.styleable.SimpleExoPlayerView_shutter_background_color);
shutterColor = a.getColor(R.styleable.SimpleExoPlayerView_shutter_background_color, shutterColor =
shutterColor); a.getColor(R.styleable.SimpleExoPlayerView_shutter_background_color, shutterColor);
playerLayoutId = a.getResourceId(R.styleable.SimpleExoPlayerView_player_layout_id, playerLayoutId =
playerLayoutId); a.getResourceId(R.styleable.SimpleExoPlayerView_player_layout_id, playerLayoutId);
useArtwork = a.getBoolean(R.styleable.SimpleExoPlayerView_use_artwork, useArtwork); useArtwork = a.getBoolean(R.styleable.SimpleExoPlayerView_use_artwork, useArtwork);
defaultArtworkId = a.getResourceId(R.styleable.SimpleExoPlayerView_default_artwork, defaultArtworkId =
defaultArtworkId); a.getResourceId(R.styleable.SimpleExoPlayerView_default_artwork, defaultArtworkId);
useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController); useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController);
surfaceType = a.getInt(R.styleable.SimpleExoPlayerView_surface_type, surfaceType); surfaceType = a.getInt(R.styleable.SimpleExoPlayerView_surface_type, surfaceType);
resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode, resizeMode); resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode, resizeMode);
controllerShowTimeoutMs = a.getInt(R.styleable.SimpleExoPlayerView_show_timeout, controllerShowTimeoutMs =
controllerShowTimeoutMs); a.getInt(R.styleable.SimpleExoPlayerView_show_timeout, controllerShowTimeoutMs);
controllerHideOnTouch = a.getBoolean(R.styleable.SimpleExoPlayerView_hide_on_touch, controllerHideOnTouch =
controllerHideOnTouch); a.getBoolean(R.styleable.SimpleExoPlayerView_hide_on_touch, controllerHideOnTouch);
controllerAutoShow = a.getBoolean(R.styleable.SimpleExoPlayerView_auto_show, controllerAutoShow =
controllerAutoShow); a.getBoolean(R.styleable.SimpleExoPlayerView_auto_show, controllerAutoShow);
controllerHideDuringAds = controllerHideDuringAds =
a.getBoolean(R.styleable.SimpleExoPlayerView_hide_during_ads, controllerHideDuringAds); a.getBoolean(R.styleable.SimpleExoPlayerView_hide_during_ads, controllerHideDuringAds);
} finally { } finally {
@ -313,9 +313,12 @@ public final class SimpleExoPlayerView extends FrameLayout {
// Create a surface view and insert it into the content frame, if there is one. // Create a surface view and insert it into the content frame, if there is one.
if (contentFrame != null && surfaceType != SURFACE_TYPE_NONE) { if (contentFrame != null && surfaceType != SURFACE_TYPE_NONE) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams params =
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
surfaceView = surfaceType == SURFACE_TYPE_TEXTURE_VIEW ? new TextureView(context) surfaceView =
surfaceType == SURFACE_TYPE_TEXTURE_VIEW
? new TextureView(context)
: new SurfaceView(context); : new SurfaceView(context);
surfaceView.setLayoutParams(params); surfaceView.setLayoutParams(params);
contentFrame.addView(surfaceView, 0); contentFrame.addView(surfaceView, 0);
@ -372,8 +375,10 @@ public final class SimpleExoPlayerView extends FrameLayout {
* @param oldPlayerView The old view to detach from the player. * @param oldPlayerView The old view to detach from the player.
* @param newPlayerView The new view to attach to the player. * @param newPlayerView The new view to attach to the player.
*/ */
public static void switchTargetView(@NonNull SimpleExoPlayer player, public static void switchTargetView(
@Nullable SimpleExoPlayerView oldPlayerView, @Nullable SimpleExoPlayerView newPlayerView) { @NonNull SimpleExoPlayer player,
@Nullable SimpleExoPlayerView oldPlayerView,
@Nullable SimpleExoPlayerView newPlayerView) {
if (oldPlayerView == newPlayerView) { if (oldPlayerView == newPlayerView) {
return; return;
} }
@ -389,21 +394,20 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
} }
/** /** Returns the player currently set on this view, or null if no player is set. */
* Returns the player currently set on this view, or null if no player is set.
*/
public SimpleExoPlayer getPlayer() { public SimpleExoPlayer getPlayer() {
return player; return player;
} }
/** /**
* Set the {@link SimpleExoPlayer} to use. * Set the {@link SimpleExoPlayer} to use.
* <p> *
* To transition a {@link SimpleExoPlayer} from targeting one view to another, it's recommended to * <p>To transition a {@link SimpleExoPlayer} from targeting one view to another, it's recommended
* use {@link #switchTargetView(SimpleExoPlayer, SimpleExoPlayerView, SimpleExoPlayerView)} rather * to use {@link #switchTargetView(SimpleExoPlayer, SimpleExoPlayerView, SimpleExoPlayerView)}
* than this method. If you do wish to use this method directly, be sure to attach the player to * rather than this method. If you do wish to use this method directly, be sure to attach the
* the new view <em>before</em> calling {@code setPlayer(null)} to detach it from the old one. * player to the new view <em>before</em> calling {@code setPlayer(null)} to detach it from the
* This ordering is significantly more efficient and may allow for more seamless transitions. * old one. This ordering is significantly more efficient and may allow for more seamless
* transitions.
* *
* @param player The {@link SimpleExoPlayer} to use. * @param player The {@link SimpleExoPlayer} to use.
*/ */
@ -467,9 +471,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
contentFrame.setResizeMode(resizeMode); contentFrame.setResizeMode(resizeMode);
} }
/** /** Returns whether artwork is displayed if present in the media. */
* Returns whether artwork is displayed if present in the media.
*/
public boolean getUseArtwork() { public boolean getUseArtwork() {
return useArtwork; return useArtwork;
} }
@ -487,9 +489,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
} }
/** /** Returns the default artwork to display. */
* Returns the default artwork to display.
*/
public Bitmap getDefaultArtwork() { public Bitmap getDefaultArtwork() {
return defaultArtwork; return defaultArtwork;
} }
@ -507,9 +507,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
} }
/** /** Returns whether the playback controls can be shown. */
* Returns whether the playback controls can be shown.
*/
public boolean getUseController() { public boolean getUseController() {
return useController; return useController;
} }
@ -554,8 +552,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
overlayFrameLayout.requestFocus(); overlayFrameLayout.requestFocus();
return super.dispatchKeyEvent(event); return super.dispatchKeyEvent(event);
} }
boolean isDpadWhenControlHidden = isDpadKey(event.getKeyCode()) && useController boolean isDpadWhenControlHidden =
&& !controller.isVisible(); isDpadKey(event.getKeyCode()) && useController && !controller.isVisible();
maybeShowController(true); maybeShowController(true);
return isDpadWhenControlHidden || dispatchMediaKeyEvent(event) || super.dispatchKeyEvent(event); return isDpadWhenControlHidden || dispatchMediaKeyEvent(event) || super.dispatchKeyEvent(event);
} }
@ -574,17 +572,15 @@ public final class SimpleExoPlayerView extends FrameLayout {
/** /**
* Shows the playback controls. Does nothing if playback controls are disabled. * Shows the playback controls. Does nothing if playback controls are disabled.
* *
* <p>The playback controls are automatically hidden during playback after * <p>The playback controls are automatically hidden during playback after {{@link
* {{@link #getControllerShowTimeoutMs()}}. They are shown indefinitely when playback has not * #getControllerShowTimeoutMs()}}. They are shown indefinitely when playback has not started yet,
* started yet, is paused, has ended or failed. * is paused, has ended or failed.
*/ */
public void showController() { public void showController() {
showController(shouldShowControllerIndefinitely()); showController(shouldShowControllerIndefinitely());
} }
/** /** Hides the playback controls. Does nothing if playback controls are disabled. */
* Hides the playback controls. Does nothing if playback controls are disabled.
*/
public void hideController() { public void hideController() {
if (controller != null) { if (controller != null) {
controller.hide(); controller.hide();
@ -607,8 +603,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
* Sets the playback controls timeout. The playback controls are automatically hidden after this * Sets the playback controls timeout. The playback controls are automatically hidden after this
* duration of time has elapsed without user input and with playback or buffering in progress. * duration of time has elapsed without user input and with playback or buffering in progress.
* *
* @param controllerShowTimeoutMs The timeout in milliseconds. A non-positive value will cause * @param controllerShowTimeoutMs The timeout in milliseconds. A non-positive value will cause the
* the controller to remain visible indefinitely. * controller to remain visible indefinitely.
*/ */
public void setControllerShowTimeoutMs(int controllerShowTimeoutMs) { public void setControllerShowTimeoutMs(int controllerShowTimeoutMs) {
Assertions.checkState(controller != null); Assertions.checkState(controller != null);
@ -620,9 +616,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
} }
/** /** Returns whether the playback controls are hidden by touch events. */
* Returns whether the playback controls are hidden by touch events.
*/
public boolean getControllerHideOnTouch() { public boolean getControllerHideOnTouch() {
return controllerHideOnTouch; return controllerHideOnTouch;
} }
@ -680,8 +674,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
/** /**
* Sets the {@link ControlDispatcher}. * Sets the {@link ControlDispatcher}.
* *
* @param controlDispatcher The {@link ControlDispatcher}, or null to use * @param controlDispatcher The {@link ControlDispatcher}, or null to use {@link
* {@link DefaultControlDispatcher}. * DefaultControlDispatcher}.
*/ */
public void setControlDispatcher(@Nullable ControlDispatcher controlDispatcher) { public void setControlDispatcher(@Nullable ControlDispatcher controlDispatcher) {
Assertions.checkState(controller != null); Assertions.checkState(controller != null);
@ -742,11 +736,12 @@ public final class SimpleExoPlayerView extends FrameLayout {
/** /**
* Gets the view onto which video is rendered. This is a: * Gets the view onto which video is rendered. This is a:
*
* <ul> * <ul>
* <li>{@link SurfaceView} by default, or if the {@code surface_type} attribute is set to * <li>{@link SurfaceView} by default, or if the {@code surface_type} attribute is set to {@code
* {@code surface_view}.</li> * surface_view}.
* <li>{@link TextureView} if {@code surface_type} is {@code texture_view}.</li> * <li>{@link TextureView} if {@code surface_type} is {@code texture_view}.
* <li>{@code null} if {@code surface_type} is {@code none}.</li> * <li>{@code null} if {@code surface_type} is {@code none}.
* </ul> * </ul>
* *
* @return The {@link SurfaceView}, {@link TextureView} or {@code null}. * @return The {@link SurfaceView}, {@link TextureView} or {@code null}.
@ -798,9 +793,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
return true; return true;
} }
/** /** Shows the playback controls, but only if forced or shown indefinitely. */
* Shows the playback controls, but only if forced or shown indefinitely.
*/
private void maybeShowController(boolean isForced) { private void maybeShowController(boolean isForced) {
if (isPlayingAd() && controllerHideDuringAds) { if (isPlayingAd() && controllerHideDuringAds) {
return; return;
@ -819,8 +812,10 @@ public final class SimpleExoPlayerView extends FrameLayout {
return true; return true;
} }
int playbackState = player.getPlaybackState(); int playbackState = player.getPlaybackState();
return controllerAutoShow && (playbackState == Player.STATE_IDLE return controllerAutoShow
|| playbackState == Player.STATE_ENDED || !player.getPlayWhenReady()); && (playbackState == Player.STATE_IDLE
|| playbackState == Player.STATE_ENDED
|| !player.getPlayWhenReady());
} }
private void showController(boolean showIndefinitely) { private void showController(boolean showIndefinitely) {
@ -927,15 +922,19 @@ public final class SimpleExoPlayerView extends FrameLayout {
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
private boolean isDpadKey(int keyCode) { private boolean isDpadKey(int keyCode) {
return keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_UP_RIGHT return keyCode == KeyEvent.KEYCODE_DPAD_UP
|| keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_DOWN_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_UP_RIGHT
|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_DOWN_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
|| keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_UP_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_DOWN_RIGHT
|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN
|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_UP_LEFT
|| keyCode == KeyEvent.KEYCODE_DPAD_CENTER; || keyCode == KeyEvent.KEYCODE_DPAD_CENTER;
} }
private final class ComponentListener extends Player.DefaultEventListener implements TextOutput, private final class ComponentListener extends Player.DefaultEventListener
SimpleExoPlayer.VideoListener { implements TextOutput, SimpleExoPlayer.VideoListener {
// TextOutput implementation // TextOutput implementation
@ -949,8 +948,8 @@ public final class SimpleExoPlayerView extends FrameLayout {
// SimpleExoPlayer.VideoInfoListener implementation // SimpleExoPlayer.VideoInfoListener implementation
@Override @Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, public void onVideoSizeChanged(
float pixelWidthHeightRatio) { int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
if (contentFrame != null) { if (contentFrame != null) {
float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height; float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height;
contentFrame.setAspectRatio(aspectRatio); contentFrame.setAspectRatio(aspectRatio);
@ -986,7 +985,5 @@ public final class SimpleExoPlayerView extends FrameLayout {
hideController(); hideController();
} }
} }
} }
} }