StyledPlayerControlView: Fix view measurement issue

The exo_controls_background view is supposed to fill its parent,
and so previously used match_parent to do this. However, if the
parent uses wrap_content for its own dimensions, the constraints
being specified become somewhat ambiguous. The parent is supposed
to be sizing itself to wrap its children, and one of the children
is supposed to be sizing itself to match the parent.

Intuitively for this case, you'd hope that the layout logic would
size the parent to wrap its other children, and that the
match_parent child would then fill the parent with its determined
size. That's not what happens, and instead the parent ends up
expanding to occupy all of the space available to it.

This commit sets the exo_controls_background view's dimensions
to be 0dp in the layout, to stop it from influencing the size of
the parent. It's then expanded to fill the parent in code.

Issue: #8726
#minor-release
PiperOrigin-RevId: 364868301
This commit is contained in:
olly 2021-03-24 19:43:50 +00:00 committed by Oliver Woodman
parent dc4148d576
commit 2b0995635e
4 changed files with 50 additions and 27 deletions

View File

@ -18,6 +18,9 @@
* Add group setting to `PlayerNotificationManager`.
* Fix `StyledPlayerView` scrubber not reappearing correctly in some cases
([#8646](https://github.com/google/ExoPlayer/issues/8646)).
* Fix measurement of `StyledPlayerView` and `StyledPlayerControlView`
when `wrap_content` is used
([#8726](https://github.com/google/ExoPlayer/issues/8726)).
* Audio:
* Report unexpected discontinuities in
`AnalyticsListener.onAudioSinkError`

View File

@ -1582,29 +1582,6 @@ public class StyledPlayerControlView extends FrameLayout {
}
}
private void onLayoutChange(
View v,
int left,
int top,
int right,
int bottom,
int oldLeft,
int oldTop,
int oldRight,
int oldBottom) {
int width = right - left;
int height = bottom - top;
int oldWidth = oldRight - oldLeft;
int oldHeight = oldBottom - oldTop;
if ((width != oldWidth || height != oldHeight) && settingsWindow.isShowing()) {
updateSettingsWindowSize();
int xOffset = getWidth() - settingsWindow.getWidth() - settingsWindowMargin;
int yOffset = -settingsWindow.getHeight() - settingsWindowMargin;
settingsWindow.update(v, xOffset, yOffset, -1, -1);
}
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
@ -1676,6 +1653,35 @@ public class StyledPlayerControlView extends FrameLayout {
return true;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
controlViewLayoutManager.onLayout(changed, left, top, right, bottom);
}
private void onLayoutChange(
View v,
int left,
int top,
int right,
int bottom,
int oldLeft,
int oldTop,
int oldRight,
int oldBottom) {
int width = right - left;
int height = bottom - top;
int oldWidth = oldRight - oldLeft;
int oldHeight = oldBottom - oldTop;
if ((width != oldWidth || height != oldHeight) && settingsWindow.isShowing()) {
updateSettingsWindowSize();
int xOffset = getWidth() - settingsWindow.getWidth() - settingsWindowMargin;
int yOffset = -settingsWindow.getHeight() - settingsWindowMargin;
settingsWindow.update(v, xOffset, yOffset, -1, -1);
}
}
private boolean shouldShowPauseButton() {
return player != null
&& player.getPlaybackState() != Player.STATE_ENDED

View File

@ -50,6 +50,7 @@ import java.util.List;
private final StyledPlayerControlView styledPlayerControlView;
@Nullable private final View controlsBackground;
@Nullable private final ViewGroup centerControls;
@Nullable private final ViewGroup bottomBar;
@Nullable private final ViewGroup minimalControls;
@ -99,7 +100,7 @@ import java.util.List;
shownButtons = new ArrayList<>();
// Relating to Center View
View controlsBackground = styledPlayerControlView.findViewById(R.id.exo_controls_background);
controlsBackground = styledPlayerControlView.findViewById(R.id.exo_controls_background);
centerControls = styledPlayerControlView.findViewById(R.id.exo_center_controls);
// Relating to Minimal Layout
@ -464,6 +465,15 @@ import java.util.List;
}
}
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (controlsBackground != null) {
// The background view should occupy the entirety of the parent. This is done in code rather
// than in layout XML to stop the background view from influencing the size of the parent if
// it uses "wrap_content". See: https://github.com/google/ExoPlayer/issues/8726.
controlsBackground.layout(0, 0, right - left, bottom - top);
}
}
private void onLayoutChange(
View v,
int left,

View File

@ -15,10 +15,14 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 0dp dimensions are used to prevent this view from influencing the size of
the parent view if it uses "wrap_content". It is expanded to occupy the
entirety of the parent in code, after the parent's size has been
determined. See: https://github.com/google/ExoPlayer/issues/8726.
-->
<View android:id="@id/exo_controls_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/exo_black_opacity_60"/>
<FrameLayout android:id="@id/exo_bottom_bar"