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:
parent
3ecf324bb3
commit
279cc0e5ed
@ -5,11 +5,20 @@ import com.facebook.react.bridge.ReadableMap
|
|||||||
|
|
||||||
class ControlsConfig {
|
class ControlsConfig {
|
||||||
var hideSeekBar: Boolean = false
|
var hideSeekBar: Boolean = false
|
||||||
var seekIncrementMS: Int = 10000
|
|
||||||
var hideDuration: Boolean = false
|
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 hideNavigationBarOnFullScreenMode: Boolean = true
|
||||||
var hideNotificationBarOnFullScreenMode: Boolean = true
|
var hideNotificationBarOnFullScreenMode: Boolean = true
|
||||||
|
|
||||||
|
var seekIncrementMS: Int = 10000
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun parse(src: ReadableMap?): ControlsConfig {
|
fun parse(src: ReadableMap?): ControlsConfig {
|
||||||
@ -17,8 +26,15 @@ class ControlsConfig {
|
|||||||
|
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
config.hideSeekBar = ReactBridgeUtils.safeGetBool(src, "hideSeekBar", false)
|
config.hideSeekBar = ReactBridgeUtils.safeGetBool(src, "hideSeekBar", false)
|
||||||
config.seekIncrementMS = ReactBridgeUtils.safeGetInt(src, "seekIncrementMS", 10000)
|
|
||||||
config.hideDuration = ReactBridgeUtils.safeGetBool(src, "hideDuration", false)
|
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.hideNavigationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNavigationBarOnFullScreenMode", true)
|
||||||
config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNotificationBarOnFullScreenMode", true)
|
config.hideNotificationBarOnFullScreenMode = ReactBridgeUtils.safeGetBool(src, "hideNotificationBarOnFullScreenMode", true)
|
||||||
}
|
}
|
||||||
|
@ -438,6 +438,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
|
|
||||||
//Handling the playButton click event
|
//Handling the playButton click event
|
||||||
ImageButton playButton = playerControlView.findViewById(R.id.exo_play);
|
ImageButton playButton = playerControlView.findViewById(R.id.exo_play);
|
||||||
|
|
||||||
playButton.setOnClickListener((View v) -> {
|
playButton.setOnClickListener((View v) -> {
|
||||||
if (player != null && player.getPlaybackState() == Player.STATE_ENDED) {
|
if (player != null && player.getPlaybackState() == Player.STATE_ENDED) {
|
||||||
player.seekTo(0);
|
player.seekTo(0);
|
||||||
@ -466,7 +467,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
|
final ImageButton fullScreenButton = playerControlView.findViewById(R.id.exo_fullscreen);
|
||||||
fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen));
|
fullScreenButton.setOnClickListener(v -> setFullscreen(!isFullscreen));
|
||||||
updateFullScreenButtonVisibility();
|
updateFullScreenButtonVisibility();
|
||||||
refreshProgressBarVisibility();
|
refreshControlsStyles();
|
||||||
|
|
||||||
// Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player
|
// Invoking onPlaybackStateChanged and onPlayWhenReadyChanged events for Player
|
||||||
eventListener = new Player.Listener() {
|
eventListener = new Player.Listener() {
|
||||||
@ -480,6 +481,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
if (pauseButton != null && pauseButton.getVisibility() == GONE) {
|
if (pauseButton != null && pauseButton.getVisibility() == GONE) {
|
||||||
pauseButton.setVisibility(INVISIBLE);
|
pauseButton.setVisibility(INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
reLayout(playPauseControlContainer);
|
reLayout(playPauseControlContainer);
|
||||||
//Remove this eventListener once its executed. since UI will work fine once after the reLayout is done
|
//Remove this eventListener once its executed. since UI will work fine once after the reLayout is done
|
||||||
player.removeListener(eventListener);
|
player.removeListener(eventListener);
|
||||||
@ -525,38 +527,85 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight());
|
view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshProgressBarVisibility (){
|
private void refreshControlsStyles (){
|
||||||
if(playerControlView == null) return;
|
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()){
|
final ImageButton playButton = playerControlView.findViewById(R.id.exo_play);
|
||||||
exoDuration.setVisibility(GONE);
|
final ImageButton pauseButton = playerControlView.findViewById(R.id.exo_pause);
|
||||||
}else{
|
if (controlsConfig.getHidePlayPause()) {
|
||||||
exoDuration.setVisibility(VISIBLE);
|
playPauseControlContainer.setAlpha(0);
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the layout parameters of exoPosition to their default state
|
playButton.setClickable(false);
|
||||||
LinearLayout.LayoutParams defaultParam = new LinearLayout.LayoutParams(
|
pauseButton.setClickable(false);
|
||||||
LayoutParams.WRAP_CONTENT,
|
} else {
|
||||||
LayoutParams.WRAP_CONTENT
|
playPauseControlContainer.setAlpha(1.0f);
|
||||||
);
|
|
||||||
exoPosition.setLayoutParams(defaultParam);
|
playButton.setClickable(true);
|
||||||
|
pauseButton.setClickable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public void setControlsStyles(ControlsConfig controlsStyles) {
|
||||||
controlsConfig = controlsStyles;
|
controlsConfig = controlsStyles;
|
||||||
refreshProgressBarVisibility();
|
refreshControlsStyles();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -146,21 +146,35 @@ Adjust the control styles. This prop is need only if `controls={true}` and is an
|
|||||||
|
|
||||||
| Property | Type | Description |
|
| Property | Type | Description |
|
||||||
|-----------------------------------|---------|--------------------------------------------------------------------------------------------|
|
|-----------------------------------|---------|--------------------------------------------------------------------------------------------|
|
||||||
| hideSeekBar | boolean | The default value is `false`, allowing you to hide the seek bar for live broadcasts. |
|
| hidePosition | boolean | Hides the position indicator. Default is `false`. |
|
||||||
| hideDuration | boolean | The default value is `false`, allowing you to hide the duration. |
|
| hidePlayPause | boolean | Hides the play/pause button. Default is `false`. |
|
||||||
| seekIncrementMS | number | The default value is `10000`. You can change the value to increment forward and rewind. |
|
| hideForward | boolean | Hides the forward button. Default is `false`. |
|
||||||
| hideNavigationBarOnFullScreenMode | boolean | The default value is `true`, allowing you to hide the navigation bar on full-screen mode. |
|
| 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. |
|
||||||
|
| 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. |
|
| 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:
|
Example with default values:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
controlsStyles={{
|
controlsStyles={{
|
||||||
|
hidePosition: false,
|
||||||
|
hidePlayPause: false,
|
||||||
|
hideForward: false,
|
||||||
|
hideRewind: false,
|
||||||
|
hideNext: false,
|
||||||
|
hidePrevious: false,
|
||||||
|
hideFullscreen: false,
|
||||||
hideSeekBar: false,
|
hideSeekBar: false,
|
||||||
hideDuration: false,
|
hideDuration: false,
|
||||||
seekIncrementMS: 10000,
|
|
||||||
hideNavigationBarOnFullScreenMode: true,
|
hideNavigationBarOnFullScreenMode: true,
|
||||||
hideNotificationBarOnFullScreenMode: true,
|
hideNotificationBarOnFullScreenMode: true,
|
||||||
|
seekIncrementMS: 10000,
|
||||||
}}
|
}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -297,11 +297,18 @@ export type OnAudioFocusChangedData = Readonly<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
type ControlsStyles = 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>;
|
hideSeekBar?: WithDefault<boolean, false>;
|
||||||
hideDuration?: WithDefault<boolean, false>;
|
hideDuration?: WithDefault<boolean, false>;
|
||||||
seekIncrementMS?: Int32;
|
|
||||||
hideNavigationBarOnFullScreenMode?: WithDefault<boolean, true>;
|
hideNavigationBarOnFullScreenMode?: WithDefault<boolean, true>;
|
||||||
hideNotificationBarOnFullScreenMode?: WithDefault<boolean, true>;
|
hideNotificationBarOnFullScreenMode?: WithDefault<boolean, true>;
|
||||||
|
seekIncrementMS?: Int32;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type OnControlsVisibilityChange = Readonly<{
|
export type OnControlsVisibilityChange = Readonly<{
|
||||||
|
@ -251,9 +251,16 @@ export type AudioOutput = 'speaker' | 'earpiece';
|
|||||||
export type ControlsStyles = {
|
export type ControlsStyles = {
|
||||||
hideSeekBar?: boolean;
|
hideSeekBar?: boolean;
|
||||||
hideDuration?: boolean;
|
hideDuration?: boolean;
|
||||||
seekIncrementMS?: number;
|
hidePosition?: boolean;
|
||||||
|
hidePlayPause?: boolean;
|
||||||
|
hideForward?: boolean;
|
||||||
|
hideRewind?: boolean;
|
||||||
|
hideNext?: boolean;
|
||||||
|
hidePrevious?: boolean;
|
||||||
|
hideFullscreen?: boolean;
|
||||||
hideNavigationBarOnFullScreenMode?: boolean;
|
hideNavigationBarOnFullScreenMode?: boolean;
|
||||||
hideNotificationBarOnFullScreenMode?: boolean;
|
hideNotificationBarOnFullScreenMode?: boolean;
|
||||||
|
seekIncrementMS?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ReactVideoRenderLoaderProps {
|
export interface ReactVideoRenderLoaderProps {
|
||||||
|
Loading…
Reference in New Issue
Block a user