UI component improvements
- Make sure no events are posted on PlaybackControlView if it's not attached to a window. This can cause leaks. The target hide time is recorded if necessary and processed when the view is re-attached. - Deduplicated PlaybackControlView.VisibilityListener invocations. - Fixed timeouts to be more intuitive (I think). - Fixed initial visibility of PlaybackControlView when used as part of SimpleExoPlayerView. - Made some more attributes configurable from layout xml. Issue: #1908 Issue: #1919 Issue: #1923 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=135679988
This commit is contained in:
parent
97020e0bab
commit
91f8328a5f
@ -16,6 +16,8 @@
|
|||||||
package com.google.android.exoplayer2.ui;
|
package com.google.android.exoplayer2.ui;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -52,7 +54,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
|
|
||||||
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_DURATION_MS = 5000;
|
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
|
||||||
|
|
||||||
private static final int PROGRESS_BAR_MAX = 1000;
|
private static final int PROGRESS_BAR_MAX = 1000;
|
||||||
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000;
|
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000;
|
||||||
@ -74,9 +76,10 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
private VisibilityListener visibilityListener;
|
private VisibilityListener visibilityListener;
|
||||||
|
|
||||||
private boolean dragging;
|
private boolean dragging;
|
||||||
private int rewindMs = DEFAULT_REWIND_MS;
|
private int rewindMs;
|
||||||
private int fastForwardMs = DEFAULT_FAST_FORWARD_MS;
|
private int fastForwardMs;
|
||||||
private int showDurationMs = DEFAULT_SHOW_DURATION_MS;
|
private int showTimeoutMs;
|
||||||
|
private long hideAtMs;
|
||||||
|
|
||||||
private final Runnable updateProgressAction = new Runnable() {
|
private final Runnable updateProgressAction = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@ -103,6 +106,22 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
public PlaybackControlView(Context context, AttributeSet attrs, int defStyleAttr) {
|
public PlaybackControlView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
|
|
||||||
|
rewindMs = DEFAULT_REWIND_MS;
|
||||||
|
fastForwardMs = DEFAULT_FAST_FORWARD_MS;
|
||||||
|
showTimeoutMs = DEFAULT_SHOW_TIMEOUT_MS;
|
||||||
|
if (attrs != null) {
|
||||||
|
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
||||||
|
R.styleable.PlaybackControlView, 0, 0);
|
||||||
|
try {
|
||||||
|
rewindMs = a.getInt(R.styleable.PlaybackControlView_rewind_increment, rewindMs);
|
||||||
|
fastForwardMs = a.getInt(R.styleable.PlaybackControlView_fastforward_increment,
|
||||||
|
fastForwardMs);
|
||||||
|
showTimeoutMs = a.getInt(R.styleable.PlaybackControlView_show_timeout, showTimeoutMs);
|
||||||
|
} finally {
|
||||||
|
a.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
currentWindow = new Timeline.Window();
|
currentWindow = new Timeline.Window();
|
||||||
formatBuilder = new StringBuilder();
|
formatBuilder = new StringBuilder();
|
||||||
formatter = new Formatter(formatBuilder, Locale.getDefault());
|
formatter = new Formatter(formatBuilder, Locale.getDefault());
|
||||||
@ -124,7 +143,6 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
rewindButton.setOnClickListener(componentListener);
|
rewindButton.setOnClickListener(componentListener);
|
||||||
fastForwardButton = findViewById(R.id.ffwd);
|
fastForwardButton = findViewById(R.id.ffwd);
|
||||||
fastForwardButton.setOnClickListener(componentListener);
|
fastForwardButton.setOnClickListener(componentListener);
|
||||||
updateAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,6 +187,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
*/
|
*/
|
||||||
public void setRewindIncrementMs(int rewindMs) {
|
public void setRewindIncrementMs(int rewindMs) {
|
||||||
this.rewindMs = rewindMs;
|
this.rewindMs = rewindMs;
|
||||||
|
updateNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,51 +197,60 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
*/
|
*/
|
||||||
public void setFastForwardIncrementMs(int fastForwardMs) {
|
public void setFastForwardIncrementMs(int fastForwardMs) {
|
||||||
this.fastForwardMs = fastForwardMs;
|
this.fastForwardMs = fastForwardMs;
|
||||||
|
updateNavigation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the duration to show the playback control in milliseconds.
|
* Returns the playback controls timeout. The playback controls are automatically hidden after
|
||||||
|
* this duration of time has elapsed without user input.
|
||||||
*
|
*
|
||||||
* @param showDurationMs The duration in milliseconds.
|
* @return The duration in milliseconds. A non-positive value indicates that the controls will
|
||||||
|
* remain visible indefinitely.
|
||||||
*/
|
*/
|
||||||
public void setShowDurationMs(int showDurationMs) {
|
public int getShowTimeoutMs() {
|
||||||
this.showDurationMs = showDurationMs;
|
return showTimeoutMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the controller for the duration last passed to {@link #setShowDurationMs(int)}, or for
|
* Sets the playback controls timeout. The playback controls are automatically hidden after this
|
||||||
* {@link #DEFAULT_SHOW_DURATION_MS} if {@link #setShowDurationMs(int)} has not been called.
|
* duration of time has elapsed without user input.
|
||||||
|
*
|
||||||
|
* @param showTimeoutMs The duration in milliseconds. A non-positive value will cause the controls
|
||||||
|
* to remain visible indefinitely.
|
||||||
|
*/
|
||||||
|
public void setShowTimeoutMs(int showTimeoutMs) {
|
||||||
|
this.showTimeoutMs = showTimeoutMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
*/
|
*/
|
||||||
public void show() {
|
public void show() {
|
||||||
show(showDurationMs);
|
if (!isVisible()) {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows the controller for the {@code durationMs}. If {@code durationMs} is 0 the controller is
|
|
||||||
* shown until {@link #hide()} is called.
|
|
||||||
*
|
|
||||||
* @param durationMs The duration in milliseconds.
|
|
||||||
*/
|
|
||||||
public void show(int durationMs) {
|
|
||||||
setVisibility(VISIBLE);
|
setVisibility(VISIBLE);
|
||||||
if (visibilityListener != null) {
|
if (visibilityListener != null) {
|
||||||
visibilityListener.onVisibilityChange(getVisibility());
|
visibilityListener.onVisibilityChange(getVisibility());
|
||||||
}
|
}
|
||||||
updateAll();
|
updateAll();
|
||||||
showDurationMs = durationMs;
|
}
|
||||||
hideDeferred();
|
// Call hideAfterTimeout even if already visible to reset the timeout.
|
||||||
|
hideAfterTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides the controller.
|
* Hides the controller.
|
||||||
*/
|
*/
|
||||||
public void hide() {
|
public void hide() {
|
||||||
|
if (isVisible()) {
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
if (visibilityListener != null) {
|
if (visibilityListener != null) {
|
||||||
visibilityListener.onVisibilityChange(getVisibility());
|
visibilityListener.onVisibilityChange(getVisibility());
|
||||||
}
|
}
|
||||||
removeCallbacks(updateProgressAction);
|
removeCallbacks(updateProgressAction);
|
||||||
removeCallbacks(hideAction);
|
removeCallbacks(hideAction);
|
||||||
|
hideAtMs = C.TIME_UNSET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,10 +260,15 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
return getVisibility() == VISIBLE;
|
return getVisibility() == VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideDeferred() {
|
private void hideAfterTimeout() {
|
||||||
removeCallbacks(hideAction);
|
removeCallbacks(hideAction);
|
||||||
if (showDurationMs > 0) {
|
if (showTimeoutMs > 0) {
|
||||||
postDelayed(hideAction, showDurationMs);
|
hideAtMs = SystemClock.uptimeMillis() + showTimeoutMs;
|
||||||
|
if (isAttachedToWindow()) {
|
||||||
|
postDelayed(hideAction, showTimeoutMs);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hideAtMs = C.TIME_UNSET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +279,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePlayPauseButton() {
|
private void updatePlayPauseButton() {
|
||||||
if (!isVisible()) {
|
if (!isVisible() || !isAttachedToWindow()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean playing = player != null && player.getPlayWhenReady();
|
boolean playing = player != null && player.getPlayWhenReady();
|
||||||
@ -258,7 +291,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateNavigation() {
|
private void updateNavigation() {
|
||||||
if (!isVisible()) {
|
if (!isVisible() || !isAttachedToWindow()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Timeline currentTimeline = player != null ? player.getCurrentTimeline() : null;
|
Timeline currentTimeline = player != null ? player.getCurrentTimeline() : null;
|
||||||
@ -276,13 +309,13 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
setButtonEnabled(enablePrevious , previousButton);
|
setButtonEnabled(enablePrevious , previousButton);
|
||||||
setButtonEnabled(enableNext, nextButton);
|
setButtonEnabled(enableNext, nextButton);
|
||||||
setButtonEnabled(isSeekable, fastForwardButton);
|
setButtonEnabled(fastForwardMs > 0 && isSeekable, fastForwardButton);
|
||||||
setButtonEnabled(isSeekable, rewindButton);
|
setButtonEnabled(rewindMs > 0 && isSeekable, rewindButton);
|
||||||
progressBar.setEnabled(isSeekable);
|
progressBar.setEnabled(isSeekable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateProgress() {
|
private void updateProgress() {
|
||||||
if (!isVisible()) {
|
if (!isVisible() || !isAttachedToWindow()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long duration = player == null ? 0 : player.getDuration();
|
long duration = player == null ? 0 : player.getDuration();
|
||||||
@ -377,13 +410,40 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void rewind() {
|
private void rewind() {
|
||||||
|
if (rewindMs <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
player.seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0));
|
player.seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fastForward() {
|
private void fastForward() {
|
||||||
|
if (fastForwardMs <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
player.seekTo(Math.min(player.getCurrentPosition() + fastForwardMs, player.getDuration()));
|
player.seekTo(Math.min(player.getCurrentPosition() + fastForwardMs, player.getDuration()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
if (hideAtMs != C.TIME_UNSET) {
|
||||||
|
long delayMs = hideAtMs - SystemClock.uptimeMillis();
|
||||||
|
if (delayMs <= 0) {
|
||||||
|
hide();
|
||||||
|
} else {
|
||||||
|
postDelayed(hideAction, delayMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
removeCallbacks(updateProgressAction);
|
||||||
|
removeCallbacks(hideAction);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||||
if (player == null || event.getAction() != KeyEvent.ACTION_DOWN) {
|
if (player == null || event.getAction() != KeyEvent.ACTION_DOWN) {
|
||||||
@ -440,7 +500,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
dragging = false;
|
dragging = false;
|
||||||
player.seekTo(positionValue(seekBar.getProgress()));
|
player.seekTo(positionValue(seekBar.getProgress()));
|
||||||
hideDeferred();
|
hideAfterTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -485,7 +545,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||||||
} else if (playButton == view) {
|
} else if (playButton == view) {
|
||||||
player.setPlayWhenReady(!player.getPlayWhenReady());
|
player.setPlayWhenReady(!player.getPlayWhenReady());
|
||||||
}
|
}
|
||||||
hideDeferred();
|
hideAfterTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,10 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
private final AspectRatioFrameLayout layout;
|
private final AspectRatioFrameLayout layout;
|
||||||
private final PlaybackControlView controller;
|
private final PlaybackControlView controller;
|
||||||
private final ComponentListener componentListener;
|
private final ComponentListener componentListener;
|
||||||
|
|
||||||
private SimpleExoPlayer player;
|
private SimpleExoPlayer player;
|
||||||
private boolean useController = true;
|
private boolean useController = true;
|
||||||
|
private int controllerShowTimeoutMs;
|
||||||
|
|
||||||
public SimpleExoPlayerView(Context context) {
|
public SimpleExoPlayerView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@ -64,6 +66,9 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
|
|
||||||
boolean useTextureView = false;
|
boolean useTextureView = false;
|
||||||
int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
||||||
|
int rewindMs = PlaybackControlView.DEFAULT_REWIND_MS;
|
||||||
|
int fastForwardMs = PlaybackControlView.DEFAULT_FAST_FORWARD_MS;
|
||||||
|
int controllerShowTimeoutMs = PlaybackControlView.DEFAULT_SHOW_TIMEOUT_MS;
|
||||||
if (attrs != null) {
|
if (attrs != null) {
|
||||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
||||||
R.styleable.SimpleExoPlayerView, 0, 0);
|
R.styleable.SimpleExoPlayerView, 0, 0);
|
||||||
@ -73,6 +78,11 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
useTextureView);
|
useTextureView);
|
||||||
resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode,
|
resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode,
|
||||||
AspectRatioFrameLayout.RESIZE_MODE_FIT);
|
AspectRatioFrameLayout.RESIZE_MODE_FIT);
|
||||||
|
rewindMs = a.getInt(R.styleable.SimpleExoPlayerView_rewind_increment, rewindMs);
|
||||||
|
fastForwardMs = a.getInt(R.styleable.SimpleExoPlayerView_fastforward_increment,
|
||||||
|
fastForwardMs);
|
||||||
|
controllerShowTimeoutMs = a.getInt(R.styleable.SimpleExoPlayerView_show_timeout,
|
||||||
|
controllerShowTimeoutMs);
|
||||||
} finally {
|
} finally {
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
@ -82,12 +92,17 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
componentListener = new ComponentListener();
|
componentListener = new ComponentListener();
|
||||||
layout = (AspectRatioFrameLayout) findViewById(R.id.video_frame);
|
layout = (AspectRatioFrameLayout) findViewById(R.id.video_frame);
|
||||||
layout.setResizeMode(resizeMode);
|
layout.setResizeMode(resizeMode);
|
||||||
controller = (PlaybackControlView) findViewById(R.id.control);
|
|
||||||
shutterView = findViewById(R.id.shutter);
|
shutterView = findViewById(R.id.shutter);
|
||||||
subtitleLayout = (SubtitleView) findViewById(R.id.subtitles);
|
subtitleLayout = (SubtitleView) findViewById(R.id.subtitles);
|
||||||
subtitleLayout.setUserDefaultStyle();
|
subtitleLayout.setUserDefaultStyle();
|
||||||
subtitleLayout.setUserDefaultTextSize();
|
subtitleLayout.setUserDefaultTextSize();
|
||||||
|
|
||||||
|
controller = (PlaybackControlView) findViewById(R.id.control);
|
||||||
|
controller.hide();
|
||||||
|
controller.setRewindIncrementMs(rewindMs);
|
||||||
|
controller.setFastForwardIncrementMs(fastForwardMs);
|
||||||
|
this.controllerShowTimeoutMs = controllerShowTimeoutMs;
|
||||||
|
|
||||||
View view = useTextureView ? new TextureView(context) : new SurfaceView(context);
|
View view = useTextureView ? new TextureView(context) : new SurfaceView(context);
|
||||||
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
|
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
@ -122,6 +137,9 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
this.player.setVideoSurface(null);
|
this.player.setVideoSurface(null);
|
||||||
}
|
}
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
if (useController) {
|
||||||
|
controller.setPlayer(player);
|
||||||
|
}
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
if (surfaceView instanceof TextureView) {
|
if (surfaceView instanceof TextureView) {
|
||||||
player.setVideoTextureView((TextureView) surfaceView);
|
player.setVideoTextureView((TextureView) surfaceView);
|
||||||
@ -131,20 +149,36 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
player.setVideoListener(componentListener);
|
player.setVideoListener(componentListener);
|
||||||
player.addListener(componentListener);
|
player.addListener(componentListener);
|
||||||
player.setTextOutput(componentListener);
|
player.setTextOutput(componentListener);
|
||||||
|
maybeShowController(false);
|
||||||
} else {
|
} else {
|
||||||
shutterView.setVisibility(VISIBLE);
|
shutterView.setVisibility(VISIBLE);
|
||||||
}
|
controller.hide();
|
||||||
if (useController) {
|
|
||||||
controller.setPlayer(player);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@code useController} flag which indicates whether the playback control view should
|
* Sets the resize mode which can be of value {@link AspectRatioFrameLayout#RESIZE_MODE_FIT},
|
||||||
* be used or not. If set to {@code false} the controller is never visible and is disconnected
|
* {@link AspectRatioFrameLayout#RESIZE_MODE_FIXED_HEIGHT} or
|
||||||
* from the player.
|
* {@link AspectRatioFrameLayout#RESIZE_MODE_FIXED_WIDTH}.
|
||||||
*
|
*
|
||||||
* @param useController If {@code false} the playback control is never used.
|
* @param resizeMode The resize mode.
|
||||||
|
*/
|
||||||
|
public void setResizeMode(int resizeMode) {
|
||||||
|
layout.setResizeMode(resizeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the playback controls are enabled.
|
||||||
|
*/
|
||||||
|
public boolean getUseController() {
|
||||||
|
return useController;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether playback controls are enabled. If set to {@code false} the playback controls are
|
||||||
|
* never visible and are disconnected from the player.
|
||||||
|
*
|
||||||
|
* @param useController Whether playback controls should be enabled.
|
||||||
*/
|
*/
|
||||||
public void setUseController(boolean useController) {
|
public void setUseController(boolean useController) {
|
||||||
if (this.useController == useController) {
|
if (this.useController == useController) {
|
||||||
@ -160,14 +194,26 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the resize mode which can be of value {@link AspectRatioFrameLayout#RESIZE_MODE_FIT},
|
* Returns the playback controls timeout. The playback controls are automatically hidden after
|
||||||
* {@link AspectRatioFrameLayout#RESIZE_MODE_FIXED_HEIGHT} or
|
* this duration of time has elapsed without user input and with playback or buffering in
|
||||||
* {@link AspectRatioFrameLayout#RESIZE_MODE_FIXED_WIDTH}.
|
* progress.
|
||||||
*
|
*
|
||||||
* @param resizeMode The resize mode.
|
* @return The timeout in milliseconds. A non-positive value will cause the controller to remain
|
||||||
|
* visible indefinitely.
|
||||||
*/
|
*/
|
||||||
public void setResizeMode(int resizeMode) {
|
public int getControllerShowTimeoutMs() {
|
||||||
layout.setResizeMode(resizeMode);
|
return controllerShowTimeoutMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param controllerShowTimeoutMs The timeout in milliseconds. A non-positive value will cause
|
||||||
|
* the controller to remain visible indefinitely.
|
||||||
|
*/
|
||||||
|
public void setControllerShowTimeoutMs(int controllerShowTimeoutMs) {
|
||||||
|
this.controllerShowTimeoutMs = controllerShowTimeoutMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,15 +243,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
controller.setFastForwardIncrementMs(fastForwardMs);
|
controller.setFastForwardIncrementMs(fastForwardMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the duration to show the playback control in milliseconds.
|
|
||||||
*
|
|
||||||
* @param showDurationMs The duration in milliseconds.
|
|
||||||
*/
|
|
||||||
public void setControlShowDurationMs(int showDurationMs) {
|
|
||||||
controller.setShowDurationMs(showDurationMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the view onto which video is rendered. This is either a {@link SurfaceView} (default)
|
* Get the view onto which video is rendered. This is either a {@link SurfaceView} (default)
|
||||||
* or a {@link TextureView} if the {@code use_texture_view} view attribute has been set to true.
|
* or a {@link TextureView} if the {@code use_texture_view} view attribute has been set to true.
|
||||||
@ -218,21 +255,23 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent ev) {
|
public boolean onTouchEvent(MotionEvent ev) {
|
||||||
if (useController && ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
if (!useController || player == null || ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (controller.isVisible()) {
|
if (controller.isVisible()) {
|
||||||
controller.hide();
|
controller.hide();
|
||||||
} else {
|
} else {
|
||||||
controller.show();
|
maybeShowController(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTrackballEvent(MotionEvent ev) {
|
public boolean onTrackballEvent(MotionEvent ev) {
|
||||||
if (!useController) {
|
if (!useController || player == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
controller.show();
|
maybeShowController(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +280,20 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
return useController ? controller.dispatchKeyEvent(event) : super.dispatchKeyEvent(event);
|
return useController ? controller.dispatchKeyEvent(event) : super.dispatchKeyEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeShowController(boolean isForced) {
|
||||||
|
if (!useController || player == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int playbackState = player.getPlaybackState();
|
||||||
|
boolean showIndefinitely = playbackState == ExoPlayer.STATE_IDLE
|
||||||
|
|| playbackState == ExoPlayer.STATE_ENDED || !player.getPlayWhenReady();
|
||||||
|
boolean wasShowingIndefinitely = controller.isVisible() && controller.getShowTimeoutMs() <= 0;
|
||||||
|
controller.setShowTimeoutMs(showIndefinitely ? 0 : controllerShowTimeoutMs);
|
||||||
|
if (isForced || showIndefinitely || wasShowingIndefinitely) {
|
||||||
|
controller.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class ComponentListener implements SimpleExoPlayer.VideoListener,
|
private final class ComponentListener implements SimpleExoPlayer.VideoListener,
|
||||||
TextRenderer.Output, ExoPlayer.EventListener {
|
TextRenderer.Output, ExoPlayer.EventListener {
|
||||||
|
|
||||||
@ -278,9 +331,7 @@ public final class SimpleExoPlayerView extends FrameLayout {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||||
if (useController && playbackState == ExoPlayer.STATE_ENDED) {
|
maybeShowController(false);
|
||||||
controller.show(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,10 +20,16 @@
|
|||||||
<enum name="fixed_width" value="1"/>
|
<enum name="fixed_width" value="1"/>
|
||||||
<enum name="fixed_height" value="2"/>
|
<enum name="fixed_height" value="2"/>
|
||||||
</attr>
|
</attr>
|
||||||
|
<attr name="show_timeout" format="integer"/>
|
||||||
|
<attr name="rewind_increment" format="integer"/>
|
||||||
|
<attr name="fastforward_increment" format="integer"/>
|
||||||
|
|
||||||
<declare-styleable name="SimpleExoPlayerView">
|
<declare-styleable name="SimpleExoPlayerView">
|
||||||
<attr name="use_controller" format="boolean"/>
|
<attr name="use_controller" format="boolean"/>
|
||||||
<attr name="use_texture_view" format="boolean"/>
|
<attr name="use_texture_view" format="boolean"/>
|
||||||
|
<attr name="show_timeout"/>
|
||||||
|
<attr name="rewind_increment"/>
|
||||||
|
<attr name="fastforward_increment"/>
|
||||||
<attr name="resize_mode"/>
|
<attr name="resize_mode"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
@ -31,4 +37,10 @@
|
|||||||
<attr name="resize_mode"/>
|
<attr name="resize_mode"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="PlaybackControlView">
|
||||||
|
<attr name="show_timeout"/>
|
||||||
|
<attr name="rewind_increment"/>
|
||||||
|
<attr name="fastforward_increment"/>
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user