Fix a couple of StyledPlayerControlView bugs

1. The first time the player controls are are made visible,
   there is no animation.
2. The first time the player controls are made visible, the
   "select tracks" button isn't displayed. When tapping to
   subsequently hide the player controls, the button briefly
   becomes visible and then is hidden again. This bug is due
   to state in StyledPlayerControlViewLayoutManager being
   out of sync, resulting in StyledPlayerControlView's
   onVisibilityChange not being called properly.

After this change both of these issues should be resolved.

PiperOrigin-RevId: 336704031
This commit is contained in:
olly 2020-10-12 19:19:26 +01:00 committed by Oliver Woodman
parent 8dc6b7e8c5
commit 3149dd0ffc
4 changed files with 163 additions and 204 deletions

View File

@ -25,6 +25,7 @@
easy tapping. easy tapping.
* Show overflow button in `StyledPlayerControlView` only when there is no * Show overflow button in `StyledPlayerControlView` only when there is no
enough space. enough space.
* Fix animation when `StyledPlayerView` first shows its playback controls.
* Audio: * Audio:
* Fix the default audio sink position not advancing correctly when using * Fix the default audio sink position not advancing correctly when using
`AudioTrack`-based speed adjustment `AudioTrack`-based speed adjustment

View File

@ -459,6 +459,7 @@ public class StyledPlayerControlView extends FrameLayout {
@SuppressWarnings({ @SuppressWarnings({
"nullness:argument.type.incompatible", "nullness:argument.type.incompatible",
"nullness:assignment.type.incompatible",
"nullness:method.invocation.invalid", "nullness:method.invocation.invalid",
"nullness:methodref.receiver.bound.invalid" "nullness:methodref.receiver.bound.invalid"
}) })
@ -526,8 +527,11 @@ public class StyledPlayerControlView extends FrameLayout {
a.recycle(); a.recycle();
} }
} }
controlViewLayoutManager = new StyledPlayerControlViewLayoutManager();
controlViewLayoutManager.setAnimationEnabled(animationEnabled); LayoutInflater.from(context).inflate(controllerLayoutId, /* root= */ this);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
componentListener = new ComponentListener();
visibilityListeners = new CopyOnWriteArrayList<>(); visibilityListeners = new CopyOnWriteArrayList<>();
period = new Timeline.Period(); period = new Timeline.Period();
window = new Timeline.Window(); window = new Timeline.Window();
@ -537,13 +541,9 @@ public class StyledPlayerControlView extends FrameLayout {
playedAdGroups = new boolean[0]; playedAdGroups = new boolean[0];
extraAdGroupTimesMs = new long[0]; extraAdGroupTimesMs = new long[0];
extraPlayedAdGroups = new boolean[0]; extraPlayedAdGroups = new boolean[0];
componentListener = new ComponentListener();
controlDispatcher = new DefaultControlDispatcher(fastForwardMs, rewindMs); controlDispatcher = new DefaultControlDispatcher(fastForwardMs, rewindMs);
updateProgressAction = this::updateProgress; updateProgressAction = this::updateProgress;
LayoutInflater.from(context).inflate(controllerLayoutId, /* root= */ this);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
// Relating to Bottom Bar Left View // Relating to Bottom Bar Left View
durationView = findViewById(R.id.exo_duration); durationView = findViewById(R.id.exo_duration);
positionView = findViewById(R.id.exo_position); positionView = findViewById(R.id.exo_position);
@ -581,10 +581,10 @@ public class StyledPlayerControlView extends FrameLayout {
} else { } else {
timeBar = null; timeBar = null;
} }
if (timeBar != null) { if (timeBar != null) {
timeBar.addListener(componentListener); timeBar.addListener(componentListener);
} }
playPauseButton = findViewById(R.id.exo_play_pause); playPauseButton = findViewById(R.id.exo_play_pause);
if (playPauseButton != null) { if (playPauseButton != null) {
playPauseButton.setOnClickListener(componentListener); playPauseButton.setOnClickListener(componentListener);
@ -626,7 +626,6 @@ public class StyledPlayerControlView extends FrameLayout {
} }
resources = context.getResources(); resources = context.getResources();
buttonAlphaEnabled = buttonAlphaEnabled =
(float) resources.getInteger(R.integer.exo_media_button_opacity_percentage_enabled) / 100; (float) resources.getInteger(R.integer.exo_media_button_opacity_percentage_enabled) / 100;
buttonAlphaDisabled = buttonAlphaDisabled =
@ -634,10 +633,12 @@ public class StyledPlayerControlView extends FrameLayout {
vrButton = findViewById(R.id.exo_vr); vrButton = findViewById(R.id.exo_vr);
if (vrButton != null) { if (vrButton != null) {
setShowVrButton(showVrButton);
updateButton(/* enabled= */ false, vrButton); updateButton(/* enabled= */ false, vrButton);
} }
controlViewLayoutManager = new StyledPlayerControlViewLayoutManager(this);
controlViewLayoutManager.setAnimationEnabled(animationEnabled);
// Related to Settings List View // Related to Settings List View
String[] settingTexts = new String[2]; String[] settingTexts = new String[2];
Drawable[] settingIcons = new Drawable[2]; Drawable[] settingIcons = new Drawable[2];
@ -1071,6 +1072,11 @@ public class StyledPlayerControlView extends FrameLayout {
controlViewLayoutManager.hide(); controlViewLayoutManager.hide();
} }
/** Hides the controller without any animation. */
public void hideImmediately() {
controlViewLayoutManager.hideImmediately();
}
/** Returns whether the controller is fully visible, which means all UI controls are visible. */ /** Returns whether the controller is fully visible, which means all UI controls are visible. */
public boolean isFullyVisible() { public boolean isFullyVisible() {
return controlViewLayoutManager.isFullyVisible(); return controlViewLayoutManager.isFullyVisible();
@ -1607,7 +1613,7 @@ public class StyledPlayerControlView extends FrameLayout {
@Override @Override
public void onAttachedToWindow() { public void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
controlViewLayoutManager.onViewAttached(this); controlViewLayoutManager.onAttachedToWindow();
isAttachedToWindow = true; isAttachedToWindow = true;
if (isFullyVisible()) { if (isFullyVisible()) {
controlViewLayoutManager.resetHideCallbacks(); controlViewLayoutManager.resetHideCallbacks();
@ -1618,7 +1624,7 @@ public class StyledPlayerControlView extends FrameLayout {
@Override @Override
public void onDetachedFromWindow() { public void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
controlViewLayoutManager.onViewDetached(this); controlViewLayoutManager.onDetachedFromWindow();
isAttachedToWindow = false; isAttachedToWindow = false;
removeCallbacks(updateProgressAction); removeCallbacks(updateProgressAction);
controlViewLayoutManager.removeHideCallbacks(); controlViewLayoutManager.removeHideCallbacks();

View File

@ -47,6 +47,26 @@ import java.util.List;
// Int for defining the UX state where the views are being animated to be shown. // Int for defining the UX state where the views are being animated to be shown.
private static final int UX_STATE_ANIMATING_SHOW = 4; private static final int UX_STATE_ANIMATING_SHOW = 4;
private final StyledPlayerControlView styledPlayerControlView;
@Nullable private final ViewGroup embeddedTransportControls;
@Nullable private final ViewGroup bottomBar;
@Nullable private final ViewGroup minimalControls;
@Nullable private final ViewGroup basicControls;
@Nullable private final ViewGroup extraControls;
@Nullable private final ViewGroup extraControlsScrollView;
@Nullable private final ViewGroup timeView;
@Nullable private final View timeBar;
@Nullable private final View overflowShowButton;
private final AnimatorSet hideMainBarsAnimator;
private final AnimatorSet hideProgressBarAnimator;
private final AnimatorSet hideAllBarsAnimator;
private final AnimatorSet showMainBarsAnimator;
private final AnimatorSet showAllBarsAnimator;
private final ValueAnimator overflowShowAnimator;
private final ValueAnimator overflowHideAnimator;
private final Runnable showAllBarsRunnable; private final Runnable showAllBarsRunnable;
private final Runnable hideAllBarsRunnable; private final Runnable hideAllBarsRunnable;
private final Runnable hideProgressBarRunnable; private final Runnable hideProgressBarRunnable;
@ -57,32 +77,16 @@ import java.util.List;
private final List<View> shownButtons; private final List<View> shownButtons;
private int uxState; private int uxState;
private boolean initiallyHidden;
private boolean isMinimalMode; private boolean isMinimalMode;
private boolean needToShowBars; private boolean needToShowBars;
private boolean animationEnabled; private boolean animationEnabled;
@Nullable private StyledPlayerControlView styledPlayerControlView; @SuppressWarnings({
"nullness:method.invocation.invalid",
@Nullable private ViewGroup embeddedTransportControls; "nullness:methodref.receiver.bound.invalid"
@Nullable private ViewGroup bottomBar; })
@Nullable private ViewGroup minimalControls; public StyledPlayerControlViewLayoutManager(StyledPlayerControlView styledPlayerControlView) {
@Nullable private ViewGroup basicControls; this.styledPlayerControlView = styledPlayerControlView;
@Nullable private ViewGroup extraControls;
@Nullable private ViewGroup extraControlsScrollView;
@Nullable private ViewGroup timeView;
@Nullable private View timeBar;
@Nullable private View overflowShowButton;
@Nullable private AnimatorSet hideMainBarsAnimator;
@Nullable private AnimatorSet hideProgressBarAnimator;
@Nullable private AnimatorSet hideAllBarsAnimator;
@Nullable private AnimatorSet showMainBarsAnimator;
@Nullable private AnimatorSet showAllBarsAnimator;
@Nullable private ValueAnimator overflowShowAnimator;
@Nullable private ValueAnimator overflowHideAnimator;
public StyledPlayerControlViewLayoutManager() {
showAllBarsRunnable = this::showAllBars; showAllBarsRunnable = this::showAllBars;
hideAllBarsRunnable = this::hideAllBars; hideAllBarsRunnable = this::hideAllBars;
hideProgressBarRunnable = this::hideProgressBar; hideProgressBarRunnable = this::hideProgressBar;
@ -92,112 +96,35 @@ import java.util.List;
animationEnabled = true; animationEnabled = true;
uxState = UX_STATE_ALL_VISIBLE; uxState = UX_STATE_ALL_VISIBLE;
shownButtons = new ArrayList<>(); shownButtons = new ArrayList<>();
}
public void show() {
initiallyHidden = false;
if (this.styledPlayerControlView == null) {
return;
}
StyledPlayerControlView styledPlayerControlView = this.styledPlayerControlView;
if (!styledPlayerControlView.isVisible()) {
styledPlayerControlView.setVisibility(View.VISIBLE);
styledPlayerControlView.updateAll();
styledPlayerControlView.requestPlayPauseFocus();
}
styledPlayerControlView.post(showAllBarsRunnable);
}
public void hide() {
initiallyHidden = true;
if (styledPlayerControlView == null
|| uxState == UX_STATE_ANIMATING_HIDE
|| uxState == UX_STATE_NONE_VISIBLE) {
return;
}
removeHideCallbacks();
if (!animationEnabled) {
postDelayedRunnable(hideControllerRunnable, 0);
} else if (uxState == UX_STATE_ONLY_PROGRESS_VISIBLE) {
postDelayedRunnable(hideProgressBarRunnable, 0);
} else {
postDelayedRunnable(hideAllBarsRunnable, 0);
}
}
public void setAnimationEnabled(boolean animationEnabled) {
this.animationEnabled = animationEnabled;
}
public boolean isAnimationEnabled() {
return animationEnabled;
}
public void resetHideCallbacks() {
if (uxState == UX_STATE_ANIMATING_HIDE) {
return;
}
removeHideCallbacks();
int showTimeoutMs =
styledPlayerControlView != null ? styledPlayerControlView.getShowTimeoutMs() : 0;
if (showTimeoutMs > 0) {
if (!animationEnabled) {
postDelayedRunnable(hideControllerRunnable, showTimeoutMs);
} else if (uxState == UX_STATE_ONLY_PROGRESS_VISIBLE) {
postDelayedRunnable(hideProgressBarRunnable, ANIMATION_INTERVAL_MS);
} else {
postDelayedRunnable(hideMainBarsRunnable, showTimeoutMs);
}
}
}
public void removeHideCallbacks() {
if (styledPlayerControlView == null) {
return;
}
styledPlayerControlView.removeCallbacks(hideControllerRunnable);
styledPlayerControlView.removeCallbacks(hideAllBarsRunnable);
styledPlayerControlView.removeCallbacks(hideMainBarsRunnable);
styledPlayerControlView.removeCallbacks(hideProgressBarRunnable);
}
// TODO(insun): Pass StyledPlayerControlView to constructor and reduce multiple nullchecks.
public void onViewAttached(StyledPlayerControlView v) {
styledPlayerControlView = v;
v.setVisibility(initiallyHidden ? View.GONE : View.VISIBLE);
v.addOnLayoutChangeListener(onLayoutChangeListener);
// Relating to Center View // Relating to Center View
ViewGroup centerView = v.findViewById(R.id.exo_center_view); ViewGroup centerView = styledPlayerControlView.findViewById(R.id.exo_center_view);
embeddedTransportControls = v.findViewById(R.id.exo_embedded_transport_controls); embeddedTransportControls =
styledPlayerControlView.findViewById(R.id.exo_embedded_transport_controls);
// Relating to Minimal Layout // Relating to Minimal Layout
minimalControls = v.findViewById(R.id.exo_minimal_controls); minimalControls = styledPlayerControlView.findViewById(R.id.exo_minimal_controls);
// Relating to Bottom Bar View // Relating to Bottom Bar View
ViewGroup bottomBar = v.findViewById(R.id.exo_bottom_bar); bottomBar = styledPlayerControlView.findViewById(R.id.exo_bottom_bar);
// Relating to Bottom Bar Left View // Relating to Bottom Bar Left View
timeView = v.findViewById(R.id.exo_time); timeView = styledPlayerControlView.findViewById(R.id.exo_time);
View timeBar = v.findViewById(R.id.exo_progress); timeBar = styledPlayerControlView.findViewById(R.id.exo_progress);
// Relating to Bottom Bar Right View // Relating to Bottom Bar Right View
basicControls = v.findViewById(R.id.exo_basic_controls); basicControls = styledPlayerControlView.findViewById(R.id.exo_basic_controls);
extraControls = v.findViewById(R.id.exo_extra_controls); extraControls = styledPlayerControlView.findViewById(R.id.exo_extra_controls);
extraControlsScrollView = v.findViewById(R.id.exo_extra_controls_scroll_view); extraControlsScrollView =
overflowShowButton = v.findViewById(R.id.exo_overflow_show); styledPlayerControlView.findViewById(R.id.exo_extra_controls_scroll_view);
View overflowHideButton = v.findViewById(R.id.exo_overflow_hide); overflowShowButton = styledPlayerControlView.findViewById(R.id.exo_overflow_show);
View overflowHideButton = styledPlayerControlView.findViewById(R.id.exo_overflow_hide);
if (overflowShowButton != null && overflowHideButton != null) { if (overflowShowButton != null && overflowHideButton != null) {
overflowShowButton.setOnClickListener(this::onOverflowButtonClick); overflowShowButton.setOnClickListener(this::onOverflowButtonClick);
overflowHideButton.setOnClickListener(this::onOverflowButtonClick); overflowHideButton.setOnClickListener(this::onOverflowButtonClick);
} }
this.bottomBar = bottomBar; Resources resources = styledPlayerControlView.getResources();
this.timeBar = timeBar;
Resources resources = v.getResources();
float progressBarHeight = resources.getDimension(R.dimen.exo_custom_progress_thumb_size); float progressBarHeight = resources.getDimension(R.dimen.exo_custom_progress_thumb_size);
float bottomBarHeight = resources.getDimension(R.dimen.exo_bottom_bar_height); float bottomBarHeight = resources.getDimension(R.dimen.exo_bottom_bar_height);
@ -206,7 +133,6 @@ import java.util.List;
fadeOutAnimator.addUpdateListener( fadeOutAnimator.addUpdateListener(
animation -> { animation -> {
float animatedValue = (float) animation.getAnimatedValue(); float animatedValue = (float) animation.getAnimatedValue();
if (centerView != null) { if (centerView != null) {
centerView.setAlpha(animatedValue); centerView.setAlpha(animatedValue);
} }
@ -239,7 +165,6 @@ import java.util.List;
fadeInAnimator.addUpdateListener( fadeInAnimator.addUpdateListener(
animation -> { animation -> {
float animatedValue = (float) animation.getAnimatedValue(); float animatedValue = (float) animation.getAnimatedValue();
if (centerView != null) { if (centerView != null) {
centerView.setAlpha(animatedValue); centerView.setAlpha(animatedValue);
} }
@ -276,9 +201,7 @@ import java.util.List;
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
setUxState(UX_STATE_ONLY_PROGRESS_VISIBLE); setUxState(UX_STATE_ONLY_PROGRESS_VISIBLE);
if (needToShowBars) { if (needToShowBars) {
if (styledPlayerControlView != null) { styledPlayerControlView.post(showAllBarsRunnable);
styledPlayerControlView.post(showAllBarsRunnable);
}
needToShowBars = false; needToShowBars = false;
} }
} }
@ -301,9 +224,7 @@ import java.util.List;
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
setUxState(UX_STATE_NONE_VISIBLE); setUxState(UX_STATE_NONE_VISIBLE);
if (needToShowBars) { if (needToShowBars) {
if (styledPlayerControlView != null) { styledPlayerControlView.post(showAllBarsRunnable);
styledPlayerControlView.post(showAllBarsRunnable);
}
needToShowBars = false; needToShowBars = false;
} }
} }
@ -325,9 +246,7 @@ import java.util.List;
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
setUxState(UX_STATE_NONE_VISIBLE); setUxState(UX_STATE_NONE_VISIBLE);
if (needToShowBars) { if (needToShowBars) {
if (styledPlayerControlView != null) { styledPlayerControlView.post(showAllBarsRunnable);
styledPlayerControlView.post(showAllBarsRunnable);
}
needToShowBars = false; needToShowBars = false;
} }
} }
@ -420,14 +339,78 @@ import java.util.List;
}); });
} }
public void onViewDetached(StyledPlayerControlView v) { public void show() {
v.removeOnLayoutChangeListener(onLayoutChangeListener); if (!styledPlayerControlView.isVisible()) {
styledPlayerControlView.setVisibility(View.VISIBLE);
styledPlayerControlView.updateAll();
styledPlayerControlView.requestPlayPauseFocus();
}
showAllBars();
}
public void hide() {
if (uxState == UX_STATE_ANIMATING_HIDE || uxState == UX_STATE_NONE_VISIBLE) {
return;
}
removeHideCallbacks();
if (!animationEnabled) {
hideController();
} else if (uxState == UX_STATE_ONLY_PROGRESS_VISIBLE) {
hideProgressBar();
} else {
hideAllBars();
}
}
public void hideImmediately() {
if (uxState == UX_STATE_ANIMATING_HIDE || uxState == UX_STATE_NONE_VISIBLE) {
return;
}
removeHideCallbacks();
hideController();
}
public void setAnimationEnabled(boolean animationEnabled) {
this.animationEnabled = animationEnabled;
}
public boolean isAnimationEnabled() {
return animationEnabled;
}
public void resetHideCallbacks() {
if (uxState == UX_STATE_ANIMATING_HIDE) {
return;
}
removeHideCallbacks();
int showTimeoutMs = styledPlayerControlView.getShowTimeoutMs();
if (showTimeoutMs > 0) {
if (!animationEnabled) {
postDelayedRunnable(hideControllerRunnable, showTimeoutMs);
} else if (uxState == UX_STATE_ONLY_PROGRESS_VISIBLE) {
postDelayedRunnable(hideProgressBarRunnable, ANIMATION_INTERVAL_MS);
} else {
postDelayedRunnable(hideMainBarsRunnable, showTimeoutMs);
}
}
}
public void removeHideCallbacks() {
styledPlayerControlView.removeCallbacks(hideControllerRunnable);
styledPlayerControlView.removeCallbacks(hideAllBarsRunnable);
styledPlayerControlView.removeCallbacks(hideMainBarsRunnable);
styledPlayerControlView.removeCallbacks(hideProgressBarRunnable);
}
public void onAttachedToWindow() {
styledPlayerControlView.addOnLayoutChangeListener(onLayoutChangeListener);
}
public void onDetachedFromWindow() {
styledPlayerControlView.removeOnLayoutChangeListener(onLayoutChangeListener);
} }
public boolean isFullyVisible() { public boolean isFullyVisible() {
if (styledPlayerControlView == null) {
return false;
}
return uxState == UX_STATE_ALL_VISIBLE && styledPlayerControlView.isVisible(); return uxState == UX_STATE_ALL_VISIBLE && styledPlayerControlView.isVisible();
} }
@ -455,18 +438,15 @@ import java.util.List;
private void setUxState(int uxState) { private void setUxState(int uxState) {
int prevUxState = this.uxState; int prevUxState = this.uxState;
this.uxState = uxState; this.uxState = uxState;
if (styledPlayerControlView != null) { if (uxState == UX_STATE_NONE_VISIBLE) {
StyledPlayerControlView styledPlayerControlView = this.styledPlayerControlView; styledPlayerControlView.setVisibility(View.GONE);
if (uxState == UX_STATE_NONE_VISIBLE) { } else if (prevUxState == UX_STATE_NONE_VISIBLE) {
styledPlayerControlView.setVisibility(View.GONE); styledPlayerControlView.setVisibility(View.VISIBLE);
} else if (prevUxState == UX_STATE_NONE_VISIBLE) { }
styledPlayerControlView.setVisibility(View.VISIBLE); // TODO(insun): Notify specific uxState. Currently reuses legacy visibility listener for API
} // compatibility.
// TODO(insun): Notify specific uxState. Currently reuses legacy visibility listener for API if (prevUxState != uxState) {
// compatibility. styledPlayerControlView.notifyOnVisibilityChange();
if (prevUxState != uxState) {
styledPlayerControlView.notifyOnVisibilityChange();
}
} }
} }
@ -494,9 +474,9 @@ import java.util.List;
private void onOverflowButtonClick(View v) { private void onOverflowButtonClick(View v) {
resetHideCallbacks(); resetHideCallbacks();
if (v.getId() == R.id.exo_overflow_show && overflowShowAnimator != null) { if (v.getId() == R.id.exo_overflow_show) {
overflowShowAnimator.start(); overflowShowAnimator.start();
} else if (v.getId() == R.id.exo_overflow_hide && overflowHideAnimator != null) { } else if (v.getId() == R.id.exo_overflow_hide) {
overflowHideAnimator.start(); overflowHideAnimator.start();
} }
} }
@ -510,14 +490,10 @@ import java.util.List;
switch (uxState) { switch (uxState) {
case UX_STATE_NONE_VISIBLE: case UX_STATE_NONE_VISIBLE:
if (showAllBarsAnimator != null) { showAllBarsAnimator.start();
showAllBarsAnimator.start();
}
break; break;
case UX_STATE_ONLY_PROGRESS_VISIBLE: case UX_STATE_ONLY_PROGRESS_VISIBLE:
if (showMainBarsAnimator != null) { showMainBarsAnimator.start();
showMainBarsAnimator.start();
}
break; break;
case UX_STATE_ANIMATING_HIDE: case UX_STATE_ANIMATING_HIDE:
needToShowBars = true; needToShowBars = true;
@ -531,23 +507,14 @@ import java.util.List;
} }
private void hideAllBars() { private void hideAllBars() {
if (hideAllBarsAnimator == null) {
return;
}
hideAllBarsAnimator.start(); hideAllBarsAnimator.start();
} }
private void hideProgressBar() { private void hideProgressBar() {
if (hideProgressBarAnimator == null) {
return;
}
hideProgressBarAnimator.start(); hideProgressBarAnimator.start();
} }
private void hideMainBars() { private void hideMainBars() {
if (hideMainBarsAnimator == null) {
return;
}
hideMainBarsAnimator.start(); hideMainBarsAnimator.start();
postDelayedRunnable(hideProgressBarRunnable, ANIMATION_INTERVAL_MS); postDelayedRunnable(hideProgressBarRunnable, ANIMATION_INTERVAL_MS);
} }
@ -561,7 +528,7 @@ import java.util.List;
} }
private void postDelayedRunnable(Runnable runnable, long interval) { private void postDelayedRunnable(Runnable runnable, long interval) {
if (styledPlayerControlView != null && interval >= 0) { if (interval >= 0) {
styledPlayerControlView.postDelayed(runnable, interval); styledPlayerControlView.postDelayed(runnable, interval);
} }
} }
@ -582,19 +549,14 @@ import java.util.List;
} }
private boolean shouldBeMinimalMode() { private boolean shouldBeMinimalMode() {
if (this.styledPlayerControlView == null) {
return isMinimalMode;
}
ViewGroup playerControlView = this.styledPlayerControlView;
int width = int width =
playerControlView.getWidth() styledPlayerControlView.getWidth()
- playerControlView.getPaddingLeft() - styledPlayerControlView.getPaddingLeft()
- playerControlView.getPaddingRight(); - styledPlayerControlView.getPaddingRight();
int height = int height =
playerControlView.getHeight() styledPlayerControlView.getHeight()
- playerControlView.getPaddingBottom() - styledPlayerControlView.getPaddingBottom()
- playerControlView.getPaddingTop(); - styledPlayerControlView.getPaddingTop();
int defaultModeWidth = int defaultModeWidth =
Math.max( Math.max(
getWidth(embeddedTransportControls), getWidth(timeView) + getWidth(overflowShowButton)); getWidth(embeddedTransportControls), getWidth(timeView) + getWidth(overflowShowButton));
@ -605,16 +567,11 @@ import java.util.List;
} }
private void updateLayoutForSizeChange() { private void updateLayoutForSizeChange() {
if (this.styledPlayerControlView == null) {
return;
}
StyledPlayerControlView playerControlView = this.styledPlayerControlView;
if (minimalControls != null) { if (minimalControls != null) {
minimalControls.setVisibility(isMinimalMode ? View.VISIBLE : View.INVISIBLE); minimalControls.setVisibility(isMinimalMode ? View.VISIBLE : View.INVISIBLE);
} }
View fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen); View fullScreenButton = styledPlayerControlView.findViewById(R.id.exo_fullscreen);
if (fullScreenButton != null) { if (fullScreenButton != null) {
ViewGroup parent = (ViewGroup) fullScreenButton.getParent(); ViewGroup parent = (ViewGroup) fullScreenButton.getParent();
parent.removeView(fullScreenButton); parent.removeView(fullScreenButton);
@ -629,10 +586,9 @@ import java.util.List;
} }
} }
if (timeBar != null) { if (timeBar != null) {
View timeBar = this.timeBar;
MarginLayoutParams timeBarParams = (MarginLayoutParams) timeBar.getLayoutParams(); MarginLayoutParams timeBarParams = (MarginLayoutParams) timeBar.getLayoutParams();
int timeBarMarginBottom = int timeBarMarginBottom =
playerControlView styledPlayerControlView
.getResources() .getResources()
.getDimensionPixelSize(R.dimen.exo_custom_progress_margin_bottom); .getDimensionPixelSize(R.dimen.exo_custom_progress_margin_bottom);
timeBarParams.bottomMargin = (isMinimalMode ? 0 : timeBarMarginBottom); timeBarParams.bottomMargin = (isMinimalMode ? 0 : timeBarMarginBottom);
@ -668,18 +624,14 @@ import java.util.List;
if (basicControls == null || extraControls == null) { if (basicControls == null || extraControls == null) {
return; return;
} }
ViewGroup basicControls = this.basicControls;
ViewGroup extraControls = this.extraControls;
int width = int width =
(styledPlayerControlView != null styledPlayerControlView.getWidth()
? styledPlayerControlView.getWidth() - styledPlayerControlView.getPaddingLeft()
- styledPlayerControlView.getPaddingLeft() - styledPlayerControlView.getPaddingRight();
- styledPlayerControlView.getPaddingRight() int bottomBarWidth = getWidth(timeView);
: 0);
int basicBottomBarWidth = getWidth(timeView);
for (int i = 0; i < basicControls.getChildCount(); ++i) { for (int i = 0; i < basicControls.getChildCount(); ++i) {
basicBottomBarWidth += basicControls.getChildAt(i).getWidth(); bottomBarWidth += basicControls.getChildAt(i).getWidth();
} }
// BasicControls keeps overflow button at least. // BasicControls keeps overflow button at least.
@ -687,7 +639,7 @@ import java.util.List;
// ExtraControls keeps overflow button and settings button at least. // ExtraControls keeps overflow button and settings button at least.
int minExtraControlsChildCount = 2; int minExtraControlsChildCount = 2;
if (basicBottomBarWidth > width) { if (bottomBarWidth > width) {
// move control views from basicControls to extraControls // move control views from basicControls to extraControls
ArrayList<View> movingChildren = new ArrayList<>(); ArrayList<View> movingChildren = new ArrayList<>();
int movingWidth = 0; int movingWidth = 0;
@ -696,7 +648,7 @@ import java.util.List;
View child = basicControls.getChildAt(index); View child = basicControls.getChildAt(index);
movingWidth += child.getWidth(); movingWidth += child.getWidth();
movingChildren.add(child); movingChildren.add(child);
if (basicBottomBarWidth - movingWidth <= width) { if (bottomBarWidth - movingWidth <= width) {
break; break;
} }
} }
@ -711,14 +663,14 @@ import java.util.List;
} }
} else { } else {
// move controls from extraControls to basicControls if possible, else do nothing // Move controls from extraControls to basicControls if possible, else do nothing.
ArrayList<View> movingChildren = new ArrayList<>(); ArrayList<View> movingChildren = new ArrayList<>();
int movingWidth = 0; int movingWidth = 0;
int startIndex = extraControls.getChildCount() - minExtraControlsChildCount - 1; int startIndex = extraControls.getChildCount() - minExtraControlsChildCount - 1;
for (int index = startIndex; index >= 0; index--) { for (int index = startIndex; index >= 0; index--) {
View child = extraControls.getChildAt(index); View child = extraControls.getChildAt(index);
movingWidth += child.getWidth(); movingWidth += child.getWidth();
if (basicBottomBarWidth + movingWidth > width) { if (bottomBarWidth + movingWidth > width) {
break; break;
} }
movingChildren.add(child); movingChildren.add(child);

View File

@ -511,11 +511,11 @@ public class StyledPlayerView extends FrameLayout implements AdsLoader.AdViewPro
this.controllerAutoShow = controllerAutoShow; this.controllerAutoShow = controllerAutoShow;
this.controllerHideDuringAds = controllerHideDuringAds; this.controllerHideDuringAds = controllerHideDuringAds;
this.useController = useController && controller != null; this.useController = useController && controller != null;
hideController();
updateContentDescription();
if (controller != null) { if (controller != null) {
controller.hideImmediately();
controller.addVisibilityListener(/* listener= */ componentListener); controller.addVisibilityListener(/* listener= */ componentListener);
} }
updateContentDescription();
} }
/** /**