StyledPlayerView: Add separate fullscreen button for minimal mode

Moving the fullscreen button around depending on modes is quite error
prone. There is currently a bug where the order of the settings cog
and fullscreen button can end up being swapped around as a result of
moving the fullscreen button to the minimal controls and back again.

It's less error prone just to have a second fullscreen button that's
always part of the minimal controls.

PiperOrigin-RevId: 347639484
This commit is contained in:
olly 2020-12-15 18:15:41 +00:00 committed by Christos Tsilopoulos
parent 7ac19ff406
commit 70ba62a281
4 changed files with 69 additions and 56 deletions

View file

@ -515,12 +515,6 @@ public class PlayerControlView extends FrameLayout {
resources.getString(R.string.exo_controls_shuffle_off_description);
}
@SuppressWarnings("ResourceType")
private static @RepeatModeUtil.RepeatToggleModes int getRepeatToggleModes(
TypedArray a, @RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
return a.getInt(R.styleable.PlayerControlView_repeat_toggle_modes, repeatToggleModes);
}
/**
* Returns the {@link Player} currently being controlled by this view, or null if no player is
* set.
@ -1318,6 +1312,12 @@ public class PlayerControlView extends FrameLayout {
return true;
}
@SuppressWarnings("ResourceType")
private static @RepeatModeUtil.RepeatToggleModes int getRepeatToggleModes(
TypedArray a, @RepeatModeUtil.RepeatToggleModes int defaultValue) {
return a.getInt(R.styleable.PlayerControlView_repeat_toggle_modes, defaultValue);
}
private final class ComponentListener
implements Player.EventListener, TimeBar.OnScrubListener, OnClickListener {

View file

@ -268,6 +268,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
* <ul>
* <li>Type: {@link ImageView}
* </ul>
* <li><b>{@code exo_minimal_fullscreen}</b> - The fullscreen button in minimal mode.
* <ul>
* <li>Type: {@link ImageView}
* </ul>
* <li><b>{@code exo_position}</b> - Text view displaying the current playback position.
* <ul>
* <li>Type: {@link TextView}
@ -430,7 +434,6 @@ public class StyledPlayerControlView extends FrameLayout {
private StyledPlayerControlViewLayoutManager controlViewLayoutManager;
private Resources resources;
// Relating to Settings List View
private int selectedMainSettingsPosition;
private RecyclerView settingsView;
private SettingsAdapter settingsAdapter;
@ -448,9 +451,9 @@ public class StyledPlayerControlView extends FrameLayout {
// TODO(insun): Add setTrackNameProvider to use customized track name provider.
private TrackNameProvider trackNameProvider;
// Relating to Bottom Bar Right View
@Nullable private ImageView subtitleButton;
@Nullable private ImageView fullScreenButton;
@Nullable private ImageView minimalFullScreenButton;
@Nullable private View settingsButton;
public StyledPlayerControlView(Context context) {
@ -552,20 +555,19 @@ public class StyledPlayerControlView extends FrameLayout {
controlDispatcher = new DefaultControlDispatcher(fastForwardMs, rewindMs);
updateProgressAction = this::updateProgress;
// Relating to Bottom Bar Left View
durationView = findViewById(R.id.exo_duration);
positionView = findViewById(R.id.exo_position);
// Relating to Bottom Bar Right View
subtitleButton = findViewById(R.id.exo_subtitle);
if (subtitleButton != null) {
subtitleButton.setOnClickListener(componentListener);
}
fullScreenButton = findViewById(R.id.exo_fullscreen);
if (fullScreenButton != null) {
fullScreenButton.setVisibility(GONE);
fullScreenButton.setOnClickListener(this::onFullScreenButtonClicked);
}
initializeFullScreenButton(fullScreenButton, this::onFullScreenButtonClicked);
minimalFullScreenButton = findViewById(R.id.exo_minimal_fullscreen);
initializeFullScreenButton(minimalFullScreenButton, this::onFullScreenButtonClicked);
settingsButton = findViewById(R.id.exo_settings);
if (settingsButton != null) {
settingsButton.setOnClickListener(componentListener);
@ -648,7 +650,6 @@ public class StyledPlayerControlView extends FrameLayout {
controlViewLayoutManager = new StyledPlayerControlViewLayoutManager(this);
controlViewLayoutManager.setAnimationEnabled(animationEnabled);
// Related to Settings List View
String[] settingTexts = new String[2];
Drawable[] settingIcons = new Drawable[2];
settingTexts[SETTINGS_PLAYBACK_SPEED_POSITION] =
@ -728,12 +729,6 @@ public class StyledPlayerControlView extends FrameLayout {
addOnLayoutChangeListener(this::onLayoutChange);
}
@SuppressWarnings("ResourceType")
private static @RepeatModeUtil.RepeatToggleModes int getRepeatToggleModes(
TypedArray a, @RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
return a.getInt(R.styleable.StyledPlayerControlView_repeat_toggle_modes, repeatToggleModes);
}
/**
* Returns the {@link Player} currently being controlled by this view, or null if no player is
* set.
@ -1057,16 +1052,9 @@ public class StyledPlayerControlView extends FrameLayout {
*/
public void setOnFullScreenModeChangedListener(
@Nullable OnFullScreenModeChangedListener listener) {
if (fullScreenButton == null) {
return;
}
onFullScreenModeChangedListener = listener;
if (onFullScreenModeChangedListener == null) {
fullScreenButton.setVisibility(GONE);
} else {
fullScreenButton.setVisibility(VISIBLE);
}
updateFullScreenButtonVisibility(fullScreenButton, listener != null);
updateFullScreenButtonVisibility(minimalFullScreenButton, listener != null);
}
/**
@ -1549,11 +1537,23 @@ public class StyledPlayerControlView extends FrameLayout {
}
private void onFullScreenButtonClicked(View v) {
if (onFullScreenModeChangedListener == null || fullScreenButton == null) {
if (onFullScreenModeChangedListener == null) {
return;
}
isFullScreen = !isFullScreen;
updateFullScreenButtonForState(fullScreenButton, isFullScreen);
updateFullScreenButtonForState(minimalFullScreenButton, isFullScreen);
if (onFullScreenModeChangedListener != null) {
onFullScreenModeChangedListener.onFullScreenModeChanged(isFullScreen);
}
}
private void updateFullScreenButtonForState(
@Nullable ImageView fullScreenButton, boolean isFullScreen) {
if (fullScreenButton == null) {
return;
}
if (isFullScreen) {
fullScreenButton.setImageDrawable(fullScreenExitDrawable);
fullScreenButton.setContentDescription(fullScreenExitContentDescription);
@ -1561,10 +1561,6 @@ public class StyledPlayerControlView extends FrameLayout {
fullScreenButton.setImageDrawable(fullScreenEnterDrawable);
fullScreenButton.setContentDescription(fullScreenEnterContentDescription);
}
if (onFullScreenModeChangedListener != null) {
onFullScreenModeChangedListener.onFullScreenModeChanged(isFullScreen);
}
}
private void onSettingViewClicked(int position) {
@ -1751,6 +1747,32 @@ public class StyledPlayerControlView extends FrameLayout {
return true;
}
private static void initializeFullScreenButton(View fullScreenButton, OnClickListener listener) {
if (fullScreenButton == null) {
return;
}
fullScreenButton.setVisibility(GONE);
fullScreenButton.setOnClickListener(listener);
}
private static void updateFullScreenButtonVisibility(
@Nullable View fullScreenButton, boolean visible) {
if (fullScreenButton == null) {
return;
}
if (visible) {
fullScreenButton.setVisibility(VISIBLE);
} else {
fullScreenButton.setVisibility(GONE);
}
}
@SuppressWarnings("ResourceType")
private static @RepeatModeUtil.RepeatToggleModes int getRepeatToggleModes(
TypedArray a, @RepeatModeUtil.RepeatToggleModes int defaultValue) {
return a.getInt(R.styleable.StyledPlayerControlView_repeat_toggle_modes, defaultValue);
}
private final class ComponentListener
implements Player.EventListener,
TimeBar.OnScrubListener,

View file

@ -589,20 +589,6 @@ import java.util.List;
minimalControls.setVisibility(isMinimalMode ? View.VISIBLE : View.INVISIBLE);
}
View fullScreenButton = styledPlayerControlView.findViewById(R.id.exo_fullscreen);
if (fullScreenButton != null) {
ViewGroup parent = (ViewGroup) fullScreenButton.getParent();
parent.removeView(fullScreenButton);
if (isMinimalMode && minimalControls != null) {
minimalControls.addView(fullScreenButton);
} else if (!isMinimalMode && basicControls != null) {
int index = Math.max(0, basicControls.getChildCount() - 1);
basicControls.addView(fullScreenButton, index);
} else {
parent.addView(fullScreenButton);
}
}
if (timeBar != null) {
MarginLayoutParams timeBarParams = (MarginLayoutParams) timeBar.getLayoutParams();
int timeBarMarginBottom =

View file

@ -56,24 +56,24 @@
android:layout_gravity="center_vertical|end"
android:layoutDirection="ltr">
<ImageButton android:id="@+id/exo_vr"
style="@style/ExoStyledControls.Button.Bottom.VR"/>
<ImageButton android:id="@+id/exo_shuffle"
style="@style/ExoStyledControls.Button.Bottom.Shuffle"/>
<ImageButton android:id="@+id/exo_repeat_toggle"
style="@style/ExoStyledControls.Button.Bottom.RepeatToggle"/>
<ImageButton android:id="@+id/exo_vr"
style="@style/ExoStyledControls.Button.Bottom.VR"/>
<ImageButton android:id="@+id/exo_subtitle"
style="@style/ExoStyledControls.Button.Bottom.CC"/>
<ImageButton android:id="@+id/exo_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
<ImageButton android:id="@+id/exo_settings"
style="@style/ExoStyledControls.Button.Bottom.Settings"/>
<ImageButton android:id="@+id/exo_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
<ImageButton android:id="@+id/exo_overflow_show"
style="@style/ExoStyledControls.Button.Bottom.OverflowShow"/>
@ -112,7 +112,12 @@
android:layout_marginBottom="@dimen/exo_styled_minimal_controls_margin_bottom"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layoutDirection="ltr"/>
android:layoutDirection="ltr">
<ImageButton android:id="@+id/exo_minimal_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
</LinearLayout>
<LinearLayout android:id="@+id/exo_center_controls"
android:layout_width="wrap_content"