8484import org .schabi .newpipe .views .player .PlayerFastSeekOverlay ;
8585
8686import java .util .List ;
87+ import java .util .Objects ;
8788import java .util .Optional ;
8889import java .util .stream .Collectors ;
8990
90- public abstract class VideoPlayerUi extends PlayerUi
91- implements SeekBar .OnSeekBarChangeListener , View .OnClickListener , View .OnLongClickListener ,
91+ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar .OnSeekBarChangeListener ,
9292 PopupMenu .OnMenuItemClickListener , PopupMenu .OnDismissListener {
9393 private static final String TAG = VideoPlayerUi .class .getSimpleName ();
9494
@@ -132,9 +132,11 @@ public abstract class VideoPlayerUi extends PlayerUi
132132
133133 private GestureDetector gestureDetector ;
134134 private BasePlayerGestureListener playerGestureListener ;
135- @ Nullable private View .OnLayoutChangeListener onLayoutChangeListener = null ;
135+ @ Nullable
136+ private View .OnLayoutChangeListener onLayoutChangeListener = null ;
136137
137- @ NonNull private final SeekbarPreviewThumbnailHolder seekbarPreviewThumbnailHolder =
138+ @ NonNull
139+ private final SeekbarPreviewThumbnailHolder seekbarPreviewThumbnailHolder =
138140 new SeekbarPreviewThumbnailHolder ();
139141
140142
@@ -187,13 +189,13 @@ private void initViews() {
187189 abstract BasePlayerGestureListener buildGestureListener ();
188190
189191 protected void initListeners () {
190- binding .qualityTextView .setOnClickListener (this );
191- binding .playbackSpeed .setOnClickListener (this );
192+ binding .qualityTextView .setOnClickListener (makeOnClickListener ( this :: onQualityClicked ) );
193+ binding .playbackSpeed .setOnClickListener (makeOnClickListener ( this :: onPlaybackSpeedClicked ) );
192194
193195 binding .playbackSeekBar .setOnSeekBarChangeListener (this );
194- binding .captionTextView .setOnClickListener (this );
195- binding .resizeTextView .setOnClickListener (this );
196- binding .playbackLiveSync .setOnClickListener (this );
196+ binding .captionTextView .setOnClickListener (makeOnClickListener ( this :: onCaptionClicked ) );
197+ binding .resizeTextView .setOnClickListener (makeOnClickListener ( this :: onResizeClicked ) );
198+ binding .playbackLiveSync .setOnClickListener (makeOnClickListener ( player :: seekToDefault ) );
197199
198200 playerGestureListener = buildGestureListener ();
199201 gestureDetector = new GestureDetector (context , playerGestureListener );
@@ -202,20 +204,36 @@ protected void initListeners() {
202204 binding .repeatButton .setOnClickListener (v -> onRepeatClicked ());
203205 binding .shuffleButton .setOnClickListener (v -> onShuffleClicked ());
204206
205- binding .playPauseButton .setOnClickListener (this );
206- binding .playPreviousButton .setOnClickListener (this );
207- binding .playNextButton .setOnClickListener (this );
208-
209- binding .moreOptionsButton .setOnClickListener (this );
210- binding .moreOptionsButton .setOnLongClickListener (this );
211- binding .share .setOnClickListener (this );
212- binding .share .setOnLongClickListener (this );
213- binding .fullScreenButton .setOnClickListener (this );
214- binding .screenRotationButton .setOnClickListener (this );
215- binding .playWithKodi .setOnClickListener (this );
216- binding .openInBrowser .setOnClickListener (this );
217- binding .playerCloseButton .setOnClickListener (this );
218- binding .switchMute .setOnClickListener (this );
207+ binding .playPauseButton .setOnClickListener (makeOnClickListener (player ::playPause ));
208+ binding .playPreviousButton .setOnClickListener (makeOnClickListener (player ::playPrevious ));
209+ binding .playNextButton .setOnClickListener (makeOnClickListener (player ::playNext ));
210+
211+ binding .moreOptionsButton .setOnClickListener (
212+ makeOnClickListener (this ::onMoreOptionsClicked ));
213+ binding .share .setOnClickListener (makeOnClickListener (() -> {
214+ final PlayQueueItem currentItem = player .getCurrentItem ();
215+ if (currentItem != null ) {
216+ ShareUtils .shareText (context , currentItem .getTitle (),
217+ player .getVideoUrlAtCurrentTime (), currentItem .getThumbnailUrl ());
218+ }
219+ }));
220+ binding .share .setOnLongClickListener (v -> {
221+ ShareUtils .copyToClipboard (context , player .getVideoUrlAtCurrentTime ());
222+ return true ;
223+ });
224+ binding .fullScreenButton .setOnClickListener (makeOnClickListener (() -> {
225+ player .setRecovery ();
226+ NavigationHelper .playOnMainPlayer (context ,
227+ Objects .requireNonNull (player .getPlayQueue ()), true );
228+ }));
229+ binding .playWithKodi .setOnClickListener (makeOnClickListener (this ::onPlayWithKodiClicked ));
230+ binding .openInBrowser .setOnClickListener (makeOnClickListener (this ::onOpenInBrowserClicked ));
231+ binding .playerCloseButton .setOnClickListener (makeOnClickListener (() ->
232+ // set package to this app's package to prevent the intent from being seen outside
233+ context .sendBroadcast (new Intent (VideoDetailFragment .ACTION_HIDE_MAIN_PLAYER )
234+ .setPackage (App .PACKAGE_NAME ))
235+ ));
236+ binding .switchMute .setOnClickListener (makeOnClickListener (player ::toggleMute ));
219237
220238 ViewCompat .setOnApplyWindowInsetsListener (binding .itemsListPanel , (view , windowInsets ) -> {
221239 final Insets cutout = windowInsets .getInsets (WindowInsetsCompat .Type .displayCutout ());
@@ -229,11 +247,8 @@ protected void initListeners() {
229247 // player_overlays and fast_seek_overlay too. Without it they will be off-centered.
230248 onLayoutChangeListener =
231249 (v , left , top , right , bottom , oldLeft , oldTop , oldRight , oldBottom ) -> {
232- binding .playerOverlays .setPadding (
233- v .getPaddingLeft (),
234- v .getPaddingTop (),
235- v .getPaddingRight (),
236- v .getPaddingBottom ());
250+ binding .playerOverlays .setPadding (v .getPaddingLeft (), v .getPaddingTop (),
251+ v .getPaddingRight (), v .getPaddingBottom ());
237252
238253 // If we added padding to the fast seek overlay, too, it would not go under the
239254 // system ui. Instead we apply negative margins equal to the window insets of
@@ -1326,86 +1341,39 @@ private void setupSubtitleView() {
13261341 //////////////////////////////////////////////////////////////////////////*/
13271342 //region Click listeners
13281343
1329- @ Override
1330- public void onClick (final View v ) {
1331- if (DEBUG ) {
1332- Log .d (TAG , "onClick() called with: v = [" + v + "]" );
1333- }
1334- if (v .getId () == binding .resizeTextView .getId ()) {
1335- onResizeClicked ();
1336- } else if (v .getId () == binding .captionTextView .getId ()) {
1337- onCaptionClicked ();
1338- } else if (v .getId () == binding .playbackLiveSync .getId ()) {
1339- player .seekToDefault ();
1340- } else if (v .getId () == binding .playPauseButton .getId ()) {
1341- player .playPause ();
1342- } else if (v .getId () == binding .playPreviousButton .getId ()) {
1343- player .playPrevious ();
1344- } else if (v .getId () == binding .playNextButton .getId ()) {
1345- player .playNext ();
1346- } else if (v .getId () == binding .moreOptionsButton .getId ()) {
1347- onMoreOptionsClicked ();
1348- } else if (v .getId () == binding .share .getId ()) {
1349- final PlayQueueItem currentItem = player .getCurrentItem ();
1350- if (currentItem != null ) {
1351- ShareUtils .shareText (context , currentItem .getTitle (),
1352- player .getVideoUrlAtCurrentTime (), currentItem .getThumbnailUrl ());
1353- }
1354- } else if (v .getId () == binding .playWithKodi .getId ()) {
1355- onPlayWithKodiClicked ();
1356- } else if (v .getId () == binding .openInBrowser .getId ()) {
1357- onOpenInBrowserClicked ();
1358- } else if (v .getId () == binding .fullScreenButton .getId ()) {
1359- player .setRecovery ();
1360- NavigationHelper .playOnMainPlayer (context , player .getPlayQueue (), true );
1361- return ;
1362- } else if (v .getId () == binding .switchMute .getId ()) {
1363- player .toggleMute ();
1364- } else if (v .getId () == binding .playerCloseButton .getId ()) {
1365- // set package to this app's package to prevent the intent from being seen outside
1366- context .sendBroadcast (new Intent (VideoDetailFragment .ACTION_HIDE_MAIN_PLAYER )
1367- .setPackage (App .PACKAGE_NAME ));
1368- } else if (v .getId () == binding .playbackSpeed .getId ()) {
1369- onPlaybackSpeedClicked ();
1370- } else if (v .getId () == binding .qualityTextView .getId ()) {
1371- onQualityClicked ();
1372- }
1373-
1374- manageControlsAfterOnClick (v );
1375- }
1376-
13771344 /**
1378- * Manages the controls after a click occurred on the player UI.
1379- * @param v – The view that was clicked
1345+ * Create on-click listener which manages the player controls after the view on-click action.
1346+ *
1347+ * @param runnable The action to be executed.
1348+ * @return The view click listener.
13801349 */
1381- public void manageControlsAfterOnClick (@ NonNull final View v ) {
1382- if (player .getCurrentState () == STATE_COMPLETED ) {
1383- return ;
1384- }
1350+ protected View .OnClickListener makeOnClickListener (@ NonNull final Runnable runnable ) {
1351+ return v -> {
1352+ if (DEBUG ) {
1353+ Log .d (TAG , "onClick() called with: v = [" + v + "]" );
1354+ }
13851355
1386- controlsVisibilityHandler .removeCallbacksAndMessages (null );
1387- showHideShadow (true , DEFAULT_CONTROLS_DURATION );
1388- animate (binding .playbackControlRoot , true , DEFAULT_CONTROLS_DURATION ,
1389- AnimationType .ALPHA , 0 , () -> {
1390- if (player .getCurrentState () == STATE_PLAYING && !isSomePopupMenuVisible ) {
1391- if (v .getId () == binding .playPauseButton .getId ()
1392- // Hide controls in fullscreen immediately
1393- || (v .getId () == binding .screenRotationButton .getId ()
1394- && isFullscreen ())) {
1395- hideControls (0 , 0 );
1396- } else {
1397- hideControls (DEFAULT_CONTROLS_DURATION , DEFAULT_CONTROLS_HIDE_TIME );
1398- }
1399- }
1400- });
1401- }
1356+ runnable .run ();
14021357
1403- @ Override
1404- public boolean onLongClick (final View v ) {
1405- if (v .getId () == binding .share .getId ()) {
1406- ShareUtils .copyToClipboard (context , player .getVideoUrlAtCurrentTime ());
1407- }
1408- return true ;
1358+ // Manages the player controls after handling the view click.
1359+ if (player .getCurrentState () == STATE_COMPLETED ) {
1360+ return ;
1361+ }
1362+ controlsVisibilityHandler .removeCallbacksAndMessages (null );
1363+ showHideShadow (true , DEFAULT_CONTROLS_DURATION );
1364+ animate (binding .playbackControlRoot , true , DEFAULT_CONTROLS_DURATION ,
1365+ AnimationType .ALPHA , 0 , () -> {
1366+ if (player .getCurrentState () == STATE_PLAYING && !isSomePopupMenuVisible ) {
1367+ if (v == binding .playPauseButton
1368+ // Hide controls in fullscreen immediately
1369+ || (v == binding .screenRotationButton && isFullscreen ())) {
1370+ hideControls (0 , 0 );
1371+ } else {
1372+ hideControls (DEFAULT_CONTROLS_DURATION , DEFAULT_CONTROLS_HIDE_TIME );
1373+ }
1374+ }
1375+ });
1376+ };
14091377 }
14101378
14111379 public boolean onKeyDown (final int keyCode ) {
0 commit comments