feat(android): allow to hide specific controls (#4183)

* feat(android): enable to hide specific controls

* fix: ts

* fix: lint

* docs: update `controlsStyles` docs
This commit is contained in:
Kamil Moskała 2024-09-29 20:51:02 +02:00 committed by GitHub
parent 3ecf324bb3
commit 279cc0e5ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 134 additions and 41 deletions

View File

@ -5,11 +5,20 @@ import com.facebook.react.bridge.ReadableMap
class ControlsConfig {
var hideSeekBar: Boolean = false
var seekIncrementMS: Int = 10000
var hideDuration: Boolean = false
var hidePosition: Boolean = false
var hidePlayPause: Boolean = false
var hideForward: Boolean = false
var hideRewind: Boolean = false
var hideNext: Boolean = false
var hidePrevious: Boolean = false
var hideFullscreen: Boolean = false
var hideNavigationBarOnFullScreenMode: Boolean = true
var hideNotificationBarOnFullScreenMode: Boolean = true
var seekIncrementMS: Int = 10000
companion object {
@JvmStatic
fun parse(src: ReadableMap?): ControlsConfig {
@ -17,8 +26,15 @@ class ControlsConfig {
if (src != null) {
config.hideSeekBar = ReactBridgeUtils.safeGetBool(src, "hideSeekBar", false)
config.seekIncrementMS = ReactBridgeUtils.safeGetInt(src, "seekIncrementMS", 10000)
config.hideDuration = ReactBridgeUtils.safeGetBool(src, "hideDuration", false)
config.hidePosition = ReactBridgeUtils.safeGetBool(src, "hidePosition", false)
config.hidePlayPause = ReactBridgeUtils.safeGetBool(src, "hidePlayPause", false)
config.hideForward = ReactBridgeUtils.safeGetBool(src, "hideForward", false)
config.hideRewind = ReactBridgeUtils.safeGetBool(src, "hideRewind", false)
config.hideNext = ReactBridgeUtils.safeGetBool(src, "hideNext", false)
config.hidePrevious = ReactBridgeUtils.safeGetBool(src, "hidePrevious", false)
config.hideFullscreen = ReactBridgeUtils.safeGetBool(src, "hideFullscreen", false)
config.seekIncrementMS = ReactBridgeUtils.safeGetInt(src, "seekIncrementMS", 10000)
config.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNavigationBarOnFullScreenMode", true)
config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNotificationBarOnFullScreenMode", true)
}

View File

@ -438,6 +438,7 @@ public class ReactExoplayerView extends FrameLayout implements
//Handling the playButton click event
ImageButton playButton = playerControlView.findViewById(R.id.exo_play);
playButton.setOnClickListener((View v) -> {
if (player != null && player.getPlaybackState() == Player.STATE_ENDED) {
player.seekTo(0);
@ -466,7 +467,7 @@ public class ReactExoplayerView extends FrameLayout implements
final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen));
updateFullScreenButtonVisibility();
refreshProgressBarVisibility();
refreshControlsStyles();
// Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player
eventListener = new Player.Listener() {
@ -480,6 +481,7 @@ public class ReactExoplayerView extends FrameLayout implements
if (pauseButton != null && pauseButton.getVisibility() == GONE) {
pauseButton.setVisibility(INVISIBLE);
}
reLayout(playPauseControlContainer);
//Remove this eventListener once its executed. since UI will work fine once after the reLayout is done
player.removeListener(eventListener);
@ -525,38 +527,85 @@ public class ReactExoplayerView extends FrameLayout implements
view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight());
}
private void refreshProgressBarVisibility (){
private void refreshControlsStyles (){
if(playerControlView == null) return;
DefaultTimeBar exoProgress;
TextView exoDuration;
TextView exoPosition;
exoProgress = playerControlView.findViewById(R.id.exo_progress);
exoDuration = playerControlView.findViewById(R.id.exo_duration);
exoPosition = playerControlView.findViewById(R.id.exo_position);
if(controlsConfig.getHideSeekBar()){
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT,
1.0f
);
exoProgress.setVisibility(GONE);
exoDuration.setVisibility(GONE);
exoPosition.setLayoutParams(param);
}else{
exoProgress.setVisibility(VISIBLE);
if(controlsConfig.getHideDuration()){
exoDuration.setVisibility(GONE);
final ImageButton playButton = playerControlView.findViewById(R.id.exo_play);
final ImageButton pauseButton = playerControlView.findViewById(R.id.exo_pause);
if (controlsConfig.getHidePlayPause()) {
playPauseControlContainer.setAlpha(0);
playButton.setClickable(false);
pauseButton.setClickable(false);
} else {
exoDuration.setVisibility(VISIBLE);
playPauseControlContainer.setAlpha(1.0f);
playButton.setClickable(true);
pauseButton.setClickable(true);
}
// Reset the layout parameters of exoPosition to their default state
LinearLayout.LayoutParams defaultParam = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT
);
exoPosition.setLayoutParams(defaultParam);
final ImageButton forwardButton = playerControlView.findViewById(R.id.exo_ffwd);
if (controlsConfig.getHideForward()) {
forwardButton.setImageAlpha(0);
forwardButton.setClickable(false);
} else {
forwardButton.setImageAlpha(255);
forwardButton.setClickable(true);
}
final ImageButton rewindButton = playerControlView.findViewById(R.id.exo_rew);
if (controlsConfig.getHideRewind()) {
rewindButton.setImageAlpha(0);
rewindButton.setClickable(false);
} else {
rewindButton.setImageAlpha(255);
rewindButton.setClickable(true);
}
final ImageButton nextButton = playerControlView.findViewById(R.id.exo_next);
if (controlsConfig.getHideNext()) {
nextButton.setClickable(false);
nextButton.setImageAlpha(0);
} else {
nextButton.setImageAlpha(255);
nextButton.setClickable(true);
}
final ImageButton previousButton = playerControlView.findViewById(R.id.exo_prev);
if (controlsConfig.getHidePrevious()) {
previousButton.setImageAlpha(0);
previousButton.setClickable(false);
} else {
previousButton.setImageAlpha(255);
previousButton.setClickable(true);
}
final ImageButton fullscreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
if (controlsConfig.getHideFullscreen()) {
fullscreenButton.setVisibility(GONE);
} else if (fullscreenButton.getVisibility() == GONE) {
fullscreenButton.setVisibility(VISIBLE);
}
final TextView positionText = playerControlView.findViewById(R.id.exo_position);
if(controlsConfig.getHidePosition()){
positionText.setVisibility(GONE);
} else if (positionText.getVisibility() == GONE){
positionText.setVisibility(VISIBLE);
}
final DefaultTimeBar progressBar = playerControlView.findViewById(R.id.exo_progress);
if (controlsConfig.getHideSeekBar()) {
progressBar.setVisibility(INVISIBLE);
} else if (progressBar.getVisibility() == INVISIBLE) {
progressBar.setVisibility(VISIBLE);
}
final TextView durationText = playerControlView.findViewById(R.id.exo_duration);
if (controlsConfig.getHideDuration()) {
durationText.setVisibility(GONE);
} else if (durationText.getVisibility() == GONE) {
durationText.setVisibility(VISIBLE);
}
}
@ -2389,6 +2438,6 @@ public class ReactExoplayerView extends FrameLayout implements
public void setControlsStyles(ControlsConfig controlsStyles) {
controlsConfig = controlsStyles;
refreshProgressBarVisibility();
refreshControlsStyles();
}
}

View File

@ -146,21 +146,35 @@ Adjust the control styles. This prop is need only if `controls={true}` and is an
| Property | Type | Description |
|-----------------------------------|---------|--------------------------------------------------------------------------------------------|
| hidePosition | boolean | Hides the position indicator. Default is `false`. |
| hidePlayPause | boolean | Hides the play/pause button. Default is `false`. |
| hideForward | boolean | Hides the forward button. Default is `false`. |
| hideRewind | boolean | Hides the rewind button. Default is `false`. |
| hideNext | boolean | Hides the next button. Default is `false`. |
| hidePrevious | boolean | Hides the previous button. Default is `false`. |
| hideFullscreen | boolean | Hides the fullscreen button. Default is `false`. |
| hideSeekBar | boolean | The default value is `false`, allowing you to hide the seek bar for live broadcasts. |
| hideDuration | boolean | The default value is `false`, allowing you to hide the duration. |
| seekIncrementMS | number | The default value is `10000`. You can change the value to increment forward and rewind. |
| hideNavigationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the navigation bar on full-screen mode. |
| hideNotificationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the notification bar on full-screen mode. |
| seekIncrementMS | number | The default value is `10000`. You can change the value to increment forward and rewind. |
Example with default values:
```javascript
controlsStyles={{
hidePosition: false,
hidePlayPause: false,
hideForward: false,
hideRewind: false,
hideNext: false,
hidePrevious: false,
hideFullscreen: false,
hideSeekBar: false,
hideDuration: false,
seekIncrementMS: 10000,
hideNavigationBarOnFullScreenMode: true,
hideNotificationBarOnFullScreenMode: true,
seekIncrementMS: 10000,
}}
```

View File

@ -297,11 +297,18 @@ export type OnAudioFocusChangedData = Readonly<{
}>;
type ControlsStyles = Readonly<{
hidePosition?: WithDefault<boolean, false>;
hidePlayPause?: WithDefault<boolean, false>;
hideForward?: WithDefault<boolean, false>;
hideRewind?: WithDefault<boolean, false>;
hideNext?: WithDefault<boolean, false>;
hidePrevious?: WithDefault<boolean, false>;
hideFullscreen?: WithDefault<boolean, false>;
hideSeekBar?: WithDefault<boolean, false>;
hideDuration?: WithDefault<boolean, false>;
seekIncrementMS?: Int32;
hideNavigationBarOnFullScreenMode?: WithDefault<boolean, true>;
hideNotificationBarOnFullScreenMode?: WithDefault<boolean, true>;
seekIncrementMS?: Int32;
}>;
export type OnControlsVisibilityChange = Readonly<{

View File

@ -251,9 +251,16 @@ export type AudioOutput = 'speaker' | 'earpiece';
export type ControlsStyles = {
hideSeekBar?: boolean;
hideDuration?: boolean;
seekIncrementMS?: number;
hidePosition?: boolean;
hidePlayPause?: boolean;
hideForward?: boolean;
hideRewind?: boolean;
hideNext?: boolean;
hidePrevious?: boolean;
hideFullscreen?: boolean;
hideNavigationBarOnFullScreenMode?: boolean;
hideNotificationBarOnFullScreenMode?: boolean;
seekIncrementMS?: number;
};
export interface ReactVideoRenderLoaderProps {