From 0c86a4e608f7f07c686643b8b2f8c17d2763f59a Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 23 Dec 2020 06:25:57 +0530 Subject: [PATCH 1/2] Use view binding (PlayerBinding) in VideoPlayer. --- .../org/schabi/newpipe/player/BasePlayer.java | 7 - .../org/schabi/newpipe/player/MainPlayer.java | 7 +- .../schabi/newpipe/player/VideoPlayer.java | 384 +++++-------- .../newpipe/player/VideoPlayerImpl.java | 529 ++++++++---------- .../player/event/PlayerGestureListener.java | 4 +- 5 files changed, 385 insertions(+), 546 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index 8eae33de6..ea16574e9 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -225,13 +225,6 @@ public abstract class BasePlayer implements this.renderFactory = new DefaultRenderersFactory(context); } - public void setup() { - if (simpleExoPlayer == null) { - initPlayer(true); - } - initListeners(); - } - public void initPlayer(final boolean playOnReady) { if (DEBUG) { Log.d(TAG, "initPlayer() called with: playOnReady = [" + playOnReady + "]"); diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index 49c836346..fc9f110e6 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -26,6 +26,7 @@ import android.os.Binder; import android.os.IBinder; import android.util.DisplayMetrics; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -33,8 +34,8 @@ import android.view.WindowManager; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; +import org.schabi.newpipe.databinding.PlayerBinding; import org.schabi.newpipe.App; -import org.schabi.newpipe.R; import org.schabi.newpipe.util.ThemeHelper; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; @@ -102,10 +103,10 @@ public final class MainPlayer extends Service { } private void createView() { - final View layout = View.inflate(this, R.layout.player, null); + final PlayerBinding binding = PlayerBinding.inflate(LayoutInflater.from(this)); playerImpl = new VideoPlayerImpl(this); - playerImpl.setup(layout); + playerImpl.setup(binding); playerImpl.shouldUpdateOnProgress = true; NotificationUtil.getInstance().createNotificationAndStartForeground(playerImpl, this); diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java index 67ea673c3..8894646c0 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -33,21 +33,18 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.os.Build; import android.os.Handler; -import androidx.preference.PreferenceManager; import android.util.Log; - import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.PopupMenu; -import android.widget.ProgressBar; import android.widget.SeekBar; import android.widget.TextView; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; +import androidx.preference.PreferenceManager; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.PlaybackParameters; @@ -62,6 +59,7 @@ import com.google.android.exoplayer2.ui.SubtitleView; import com.google.android.exoplayer2.video.VideoListener; import org.schabi.newpipe.R; +import org.schabi.newpipe.databinding.PlayerBinding; import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.VideoStream; @@ -84,7 +82,7 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView; * * @author mauriciocolli */ -@SuppressWarnings({"WeakerAccess", "unused"}) +@SuppressWarnings({"WeakerAccess"}) public abstract class VideoPlayer extends BasePlayer implements VideoListener, SeekBar.OnSeekBarChangeListener, @@ -117,34 +115,11 @@ public abstract class VideoPlayer extends BasePlayer // Views //////////////////////////////////////////////////////////////////////////*/ - private View rootView; + protected PlayerBinding binding; - private ExpandableSurfaceView surfaceView; - private View surfaceForeground; - - private View loadingPanel; - private ImageView endScreen; - private ImageView controlAnimationView; - - private View controlsRoot; - private TextView currentDisplaySeek; - private View playerTopShadow; - private View playerBottomShadow; - - private View bottomControlsRoot; - private SeekBar playbackSeekBar; - private TextView playbackCurrentTime; - private TextView playbackEndTime; - private TextView playbackLiveSync; - private TextView playbackSpeedTextView; - - private LinearLayout topControlsRoot; - private TextView qualityTextView; - - private SubtitleView subtitleView; - - private TextView resizeView; - private TextView captionTextView; + protected SeekBar playbackSeekBar; + protected TextView qualityTextView; + protected TextView playbackSpeed; private ValueAnimator controlViewAnimator; private final Handler controlsVisibilityHandler = new Handler(); @@ -162,7 +137,7 @@ public abstract class VideoPlayer extends BasePlayer /////////////////////////////////////////////////////////////////////////// - public VideoPlayer(final String debugTag, final Context context) { + protected VideoPlayer(final String debugTag, final Context context) { super(context); this.TAG = debugTag; this.resolver = new VideoPlaybackResolver(context, dataSource, getQualityResolver()); @@ -178,54 +153,37 @@ public abstract class VideoPlayer extends BasePlayer return false; } - public void setup(final View view) { - initViews(view); - setup(); + public void setup(@NonNull final PlayerBinding playerBinding) { + initViews(playerBinding); + if (simpleExoPlayer == null) { + initPlayer(true); + } + initListeners(); } - public void initViews(final View view) { - this.rootView = view; - this.surfaceView = view.findViewById(R.id.surfaceView); - this.surfaceForeground = view.findViewById(R.id.surfaceForeground); - this.loadingPanel = view.findViewById(R.id.loading_panel); - this.endScreen = view.findViewById(R.id.endScreen); - this.controlAnimationView = view.findViewById(R.id.controlAnimationView); - this.controlsRoot = view.findViewById(R.id.playbackControlRoot); - this.currentDisplaySeek = view.findViewById(R.id.currentDisplaySeek); - this.playerTopShadow = view.findViewById(R.id.playerTopShadow); - this.playerBottomShadow = view.findViewById(R.id.playerBottomShadow); - this.playbackSeekBar = view.findViewById(R.id.playbackSeekBar); - this.playbackCurrentTime = view.findViewById(R.id.playbackCurrentTime); - this.playbackEndTime = view.findViewById(R.id.playbackEndTime); - this.playbackLiveSync = view.findViewById(R.id.playbackLiveSync); - this.playbackSpeedTextView = view.findViewById(R.id.playbackSpeed); - this.bottomControlsRoot = view.findViewById(R.id.bottomControls); - this.topControlsRoot = view.findViewById(R.id.topControls); - this.qualityTextView = view.findViewById(R.id.qualityTextView); - - this.subtitleView = view.findViewById(R.id.subtitleView); + public void initViews(@NonNull final PlayerBinding playerBinding) { + binding = playerBinding; + playbackSeekBar = (SeekBar) binding.playbackSeekBar; + qualityTextView = (TextView) binding.qualityTextView; + playbackSpeed = (TextView) binding.playbackSpeed; final float captionScale = PlayerHelper.getCaptionScale(context); final CaptionStyleCompat captionStyle = PlayerHelper.getCaptionStyle(context); - setupSubtitleView(subtitleView, captionScale, captionStyle); + setupSubtitleView(binding.subtitleView, captionScale, captionStyle); - this.resizeView = view.findViewById(R.id.resizeTextView); - resizeView.setText(PlayerHelper - .resizeTypeOf(context, getSurfaceView().getResizeMode())); + ((TextView) binding.resizeTextView).setText(PlayerHelper.resizeTypeOf(context, + binding.surfaceView.getResizeMode())); - this.captionTextView = view.findViewById(R.id.captionTextView); + playbackSeekBar.getThumb().setColorFilter(new PorterDuffColorFilter(Color.RED, + PorterDuff.Mode.SRC_IN)); + playbackSeekBar.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(Color.RED, + PorterDuff.Mode.MULTIPLY)); - playbackSeekBar.getThumb() - .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)); - this.playbackSeekBar.getProgressDrawable() - .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)); + qualityPopupMenu = new PopupMenu(context, qualityTextView); + playbackSpeedPopupMenu = new PopupMenu(context, playbackSpeed); + captionPopupMenu = new PopupMenu(context, binding.captionTextView); - this.qualityPopupMenu = new PopupMenu(context, qualityTextView); - this.playbackSpeedPopupMenu = new PopupMenu(context, playbackSpeedTextView); - this.captionPopupMenu = new PopupMenu(context, captionTextView); - - ((ProgressBar) this.loadingPanel.findViewById(R.id.progressBarLoadingPanel)) - .getIndeterminateDrawable() + binding.progressBarLoadingPanel.getIndeterminateDrawable() .setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY)); } @@ -235,11 +193,11 @@ public abstract class VideoPlayer extends BasePlayer @Override public void initListeners() { playbackSeekBar.setOnSeekBarChangeListener(this); - playbackSpeedTextView.setOnClickListener(this); - qualityTextView.setOnClickListener(this); - captionTextView.setOnClickListener(this); - resizeView.setOnClickListener(this); - playbackLiveSync.setOnClickListener(this); + binding.playbackSpeed.setOnClickListener(this); + binding.qualityTextView.setOnClickListener(this); + binding.captionTextView.setOnClickListener(this); + binding.resizeTextView.setOnClickListener(this); + binding.playbackLiveSync.setOnClickListener(this); } @Override @@ -247,11 +205,11 @@ public abstract class VideoPlayer extends BasePlayer super.initPlayer(playOnReady); // Setup video view - simpleExoPlayer.setVideoSurfaceView(surfaceView); + simpleExoPlayer.setVideoSurfaceView(binding.surfaceView); simpleExoPlayer.addVideoListener(this); // Setup subtitle view - simpleExoPlayer.addTextOutput(cues -> subtitleView.onCues(cues)); + simpleExoPlayer.addTextOutput(binding.subtitleView); // Setup audio session with onboard equalizer if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -305,7 +263,7 @@ public abstract class VideoPlayer extends BasePlayer playbackSpeedPopupMenu.getMenu().add(playbackSpeedPopupMenuGroupId, i, Menu.NONE, formatSpeed(PLAYBACK_SPEEDS[i])); } - playbackSpeedTextView.setText(formatSpeed(getPlaybackSpeed())); + playbackSpeed.setText(formatSpeed(getPlaybackSpeed())); playbackSpeedPopupMenu.setOnMenuItemClickListener(this); playbackSpeedPopupMenu.setOnDismissListener(this); } @@ -385,29 +343,29 @@ public abstract class VideoPlayer extends BasePlayer final MediaSourceTag tag = getCurrentMetadata(); final StreamInfo metadata = tag.getMetadata(); - qualityTextView.setVisibility(View.GONE); - playbackSpeedTextView.setVisibility(View.GONE); + binding.qualityTextView.setVisibility(View.GONE); + binding.playbackSpeed.setVisibility(View.GONE); - playbackEndTime.setVisibility(View.GONE); - playbackLiveSync.setVisibility(View.GONE); + binding.playbackEndTime.setVisibility(View.GONE); + binding.playbackLiveSync.setVisibility(View.GONE); switch (metadata.getStreamType()) { case AUDIO_STREAM: - surfaceView.setVisibility(View.GONE); - endScreen.setVisibility(View.VISIBLE); - playbackEndTime.setVisibility(View.VISIBLE); + binding.surfaceView.setVisibility(View.GONE); + binding.endScreen.setVisibility(View.VISIBLE); + binding.playbackEndTime.setVisibility(View.VISIBLE); break; case AUDIO_LIVE_STREAM: - surfaceView.setVisibility(View.GONE); - endScreen.setVisibility(View.VISIBLE); - playbackLiveSync.setVisibility(View.VISIBLE); + binding.surfaceView.setVisibility(View.GONE); + binding.endScreen.setVisibility(View.VISIBLE); + binding.playbackLiveSync.setVisibility(View.VISIBLE); break; case LIVE_STREAM: - surfaceView.setVisibility(View.VISIBLE); - endScreen.setVisibility(View.GONE); - playbackLiveSync.setVisibility(View.VISIBLE); + binding.surfaceView.setVisibility(View.VISIBLE); + binding.endScreen.setVisibility(View.GONE); + binding.playbackLiveSync.setVisibility(View.VISIBLE); break; case VIDEO_STREAM: @@ -420,16 +378,16 @@ public abstract class VideoPlayer extends BasePlayer selectedStreamIndex = tag.getSelectedVideoStreamIndex(); buildQualityMenu(); - qualityTextView.setVisibility(View.VISIBLE); - surfaceView.setVisibility(View.VISIBLE); + binding.qualityTextView.setVisibility(View.VISIBLE); + binding.surfaceView.setVisibility(View.VISIBLE); default: - endScreen.setVisibility(View.GONE); - playbackEndTime.setVisibility(View.VISIBLE); + binding.endScreen.setVisibility(View.GONE); + binding.playbackEndTime.setVisibility(View.VISIBLE); break; } buildPlaybackSpeedMenu(); - playbackSpeedTextView.setVisibility(View.VISIBLE); + binding.playbackSpeed.setVisibility(View.VISIBLE); } /*////////////////////////////////////////////////////////////////////////// @@ -438,6 +396,7 @@ public abstract class VideoPlayer extends BasePlayer protected abstract VideoPlaybackResolver.QualityResolver getQualityResolver(); + @Override protected void onMetadataChanged(@NonNull final MediaSourceTag tag) { super.onMetadataChanged(tag); updateStreamRelatedViews(); @@ -458,15 +417,15 @@ public abstract class VideoPlayer extends BasePlayer super.onBlocked(); controlsVisibilityHandler.removeCallbacksAndMessages(null); - animateView(controlsRoot, false, DEFAULT_CONTROLS_DURATION); + animateView(binding.playbackControlRoot, false, DEFAULT_CONTROLS_DURATION); playbackSeekBar.setEnabled(false); - playbackSeekBar.getThumb() - .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)); + playbackSeekBar.getThumb().setColorFilter(new PorterDuffColorFilter(Color.RED, + PorterDuff.Mode.SRC_IN)); - loadingPanel.setBackgroundColor(Color.BLACK); - animateView(loadingPanel, true, 0); - animateView(surfaceForeground, true, 100); + binding.loadingPanel.setBackgroundColor(Color.BLACK); + animateView(binding.loadingPanel, true, 0); + animateView(binding.surfaceForeground, true, 100); } @Override @@ -478,12 +437,13 @@ public abstract class VideoPlayer extends BasePlayer showAndAnimateControl(-1, true); playbackSeekBar.setEnabled(true); - playbackSeekBar.getThumb() - .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)); + playbackSeekBar.getThumb().setColorFilter(new PorterDuffColorFilter(Color.RED, + PorterDuff.Mode.SRC_IN)); - loadingPanel.setVisibility(View.GONE); + binding.loadingPanel.setVisibility(View.GONE); - animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200); + animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, + 200); } @Override @@ -491,7 +451,7 @@ public abstract class VideoPlayer extends BasePlayer if (DEBUG) { Log.d(TAG, "onBuffering() called"); } - loadingPanel.setBackgroundColor(Color.TRANSPARENT); + binding.loadingPanel.setBackgroundColor(Color.TRANSPARENT); } @Override @@ -500,7 +460,7 @@ public abstract class VideoPlayer extends BasePlayer Log.d(TAG, "onPaused() called"); } showControls(400); - loadingPanel.setVisibility(View.GONE); + binding.loadingPanel.setVisibility(View.GONE); } @Override @@ -516,10 +476,11 @@ public abstract class VideoPlayer extends BasePlayer super.onCompleted(); showControls(500); - animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200); - loadingPanel.setVisibility(View.GONE); + animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, + 200); + binding.loadingPanel.setVisibility(View.GONE); - animateView(surfaceForeground, true, 100); + animateView(binding.surfaceForeground, true, 100); } /*////////////////////////////////////////////////////////////////////////// @@ -527,16 +488,16 @@ public abstract class VideoPlayer extends BasePlayer //////////////////////////////////////////////////////////////////////////*/ @Override - public void onTracksChanged(final TrackGroupArray trackGroups, - final TrackSelectionArray trackSelections) { + public void onTracksChanged(@NonNull final TrackGroupArray trackGroups, + @NonNull final TrackSelectionArray trackSelections) { super.onTracksChanged(trackGroups, trackSelections); onTextTrackUpdate(); } @Override - public void onPlaybackParametersChanged(final PlaybackParameters playbackParameters) { + public void onPlaybackParametersChanged(@NonNull final PlaybackParameters playbackParameters) { super.onPlaybackParametersChanged(playbackParameters); - playbackSpeedTextView.setText(formatSpeed(playbackParameters.speed)); + playbackSpeed.setText(formatSpeed(playbackParameters.speed)); } @Override @@ -550,12 +511,12 @@ public abstract class VideoPlayer extends BasePlayer + "unappliedRotationDegrees = [" + unappliedRotationDegrees + "], " + "pixelWidthHeightRatio = [" + pixelWidthHeightRatio + "]"); } - getSurfaceView().setAspectRatio(((float) width) / height); + binding.surfaceView.setAspectRatio(((float) width) / height); } @Override public void onRenderedFirstFrame() { - animateView(surfaceForeground, false, 100); + animateView(binding.surfaceForeground, false, 100); } /*////////////////////////////////////////////////////////////////////////// @@ -565,12 +526,12 @@ public abstract class VideoPlayer extends BasePlayer private void onTextTrackUpdate() { final int textRenderer = getRendererIndex(C.TRACK_TYPE_TEXT); - if (captionTextView == null) { + if (binding == null) { return; } if (trackSelector.getCurrentMappedTrackInfo() == null || textRenderer == RENDERER_UNAVAILABLE) { - captionTextView.setVisibility(View.GONE); + binding.captionTextView.setVisibility(View.GONE); return; } @@ -593,11 +554,12 @@ public abstract class VideoPlayer extends BasePlayer if (trackSelector.getParameters().getRendererDisabled(textRenderer) || preferredLanguage == null || (!availableLanguages.contains(preferredLanguage) && !containsCaseInsensitive(availableLanguages, preferredLanguage))) { - captionTextView.setText(R.string.caption_none); + binding.captionTextView.setText(R.string.caption_none); } else { - captionTextView.setText(preferredLanguage); + binding.captionTextView.setText(preferredLanguage); } - captionTextView.setVisibility(availableLanguages.isEmpty() ? View.GONE : View.VISIBLE); + binding.captionTextView.setVisibility(availableLanguages.isEmpty() ? View.GONE + : View.VISIBLE); } /*////////////////////////////////////////////////////////////////////////// @@ -611,8 +573,8 @@ public abstract class VideoPlayer extends BasePlayer } playbackSeekBar.setMax((int) simpleExoPlayer.getDuration()); - playbackEndTime.setText(getTimeString((int) simpleExoPlayer.getDuration())); - playbackSpeedTextView.setText(formatSpeed(getPlaybackSpeed())); + binding.playbackEndTime.setText(getTimeString((int) simpleExoPlayer.getDuration())); + playbackSpeed.setText(formatSpeed(getPlaybackSpeed())); super.onPrepared(playWhenReady); } @@ -620,8 +582,8 @@ public abstract class VideoPlayer extends BasePlayer @Override public void destroy() { super.destroy(); - if (endScreen != null) { - endScreen.setImageBitmap(null); + if (binding != null) { + binding.endScreen.setImageBitmap(null); } } @@ -633,14 +595,14 @@ public abstract class VideoPlayer extends BasePlayer } if (duration != playbackSeekBar.getMax()) { - playbackEndTime.setText(getTimeString(duration)); + binding.playbackEndTime.setText(getTimeString(duration)); playbackSeekBar.setMax(duration); } if (currentState != STATE_PAUSED) { if (currentState != STATE_PAUSED_SEEK) { playbackSeekBar.setProgress(currentProgress); } - playbackCurrentTime.setText(getTimeString(currentProgress)); + binding.playbackCurrentTime.setText(getTimeString(currentProgress)); } if (simpleExoPlayer.isLoading() || bufferPercent > 90) { playbackSeekBar.setSecondaryProgress( @@ -652,7 +614,7 @@ public abstract class VideoPlayer extends BasePlayer + "currentProgress = [" + currentProgress + "], " + "duration = [" + duration + "], bufferPercent = [" + bufferPercent + "]"); } - playbackLiveSync.setClickable(!isLiveEdge()); + binding.playbackLiveSync.setClickable(!isLiveEdge()); } @Override @@ -660,7 +622,7 @@ public abstract class VideoPlayer extends BasePlayer final Bitmap loadedImage) { super.onLoadingComplete(imageUri, view, loadedImage); if (loadedImage != null) { - endScreen.setImageBitmap(loadedImage); + binding.endScreen.setImageBitmap(loadedImage); } } @@ -689,15 +651,15 @@ public abstract class VideoPlayer extends BasePlayer if (DEBUG) { Log.d(TAG, "onClick() called with: v = [" + v + "]"); } - if (v.getId() == qualityTextView.getId()) { + if (v.getId() == binding.qualityTextView.getId()) { onQualitySelectorClicked(); - } else if (v.getId() == playbackSpeedTextView.getId()) { + } else if (v.getId() == binding.playbackSpeed.getId()) { onPlaybackSpeedClicked(); - } else if (v.getId() == resizeView.getId()) { + } else if (v.getId() == binding.resizeTextView.getId()) { onResizeClicked(); - } else if (v.getId() == captionTextView.getId()) { + } else if (v.getId() == binding.captionTextView.getId()) { onCaptionClicked(); - } else if (v.getId() == playbackLiveSync.getId()) { + } else if (v.getId() == binding.playbackLiveSync.getId()) { seekToDefault(); } } @@ -732,7 +694,7 @@ public abstract class VideoPlayer extends BasePlayer final float speed = PLAYBACK_SPEEDS[speedIndex]; setPlaybackSpeed(speed); - playbackSpeedTextView.setText(formatSpeed(speed)); + playbackSpeed.setText(formatSpeed(speed)); } return false; @@ -786,16 +748,17 @@ public abstract class VideoPlayer extends BasePlayer } void onResizeClicked() { - if (getSurfaceView() != null) { - final int currentResizeMode = getSurfaceView().getResizeMode(); + if (binding != null) { + final int currentResizeMode = binding.surfaceView.getResizeMode(); final int newResizeMode = nextResizeMode(currentResizeMode); setResizeMode(newResizeMode); } } protected void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int resizeMode) { - getSurfaceView().setResizeMode(resizeMode); - getResizeView().setText(PlayerHelper.resizeTypeOf(context, resizeMode)); + binding.surfaceView.setResizeMode(resizeMode); + ((TextView) binding.resizeTextView).setText(PlayerHelper.resizeTypeOf(context, + resizeMode)); } protected abstract int nextResizeMode(@AspectRatioFrameLayout.ResizeMode int resizeMode); @@ -811,9 +774,8 @@ public abstract class VideoPlayer extends BasePlayer Log.d(TAG, "onProgressChanged() called with: " + "seekBar = [" + seekBar + "], progress = [" + progress + "]"); } - //if (fromUser) playbackCurrentTime.setText(getTimeString(progress)); if (fromUser) { - currentDisplaySeek.setText(getTimeString(progress)); + binding.currentDisplaySeek.setText(getTimeString(progress)); } } @@ -832,7 +794,7 @@ public abstract class VideoPlayer extends BasePlayer } showControls(0); - animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, true, + animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, true, DEFAULT_CONTROLS_DURATION); } @@ -847,8 +809,9 @@ public abstract class VideoPlayer extends BasePlayer simpleExoPlayer.setPlayWhenReady(true); } - playbackCurrentTime.setText(getTimeString(seekBar.getProgress())); - animateView(currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, 200); + binding.playbackCurrentTime.setText(getTimeString(seekBar.getProgress())); + animateView(binding.currentDisplaySeek, AnimationUtils.Type.SCALE_AND_ALPHA, false, + 200); if (getCurrentState() == STATE_PAUSED_SEEK) { changeState(STATE_BUFFERING); @@ -877,7 +840,8 @@ public abstract class VideoPlayer extends BasePlayer } public boolean isControlsVisible() { - return controlsRoot != null && controlsRoot.getVisibility() == View.VISIBLE; + return binding != null + && binding.playbackControlRoot.getVisibility() == View.VISIBLE; } /** @@ -900,8 +864,9 @@ public abstract class VideoPlayer extends BasePlayer } if (drawableId == -1) { - if (controlAnimationView.getVisibility() == View.VISIBLE) { - controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder(controlAnimationView, + if (binding.controlAnimationView.getVisibility() == View.VISIBLE) { + controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder( + binding.controlAnimationView, PropertyValuesHolder.ofFloat(View.ALPHA, 1.0f, 0.0f), PropertyValuesHolder.ofFloat(View.SCALE_X, 1.4f, 1.0f), PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.4f, 1.0f) @@ -909,7 +874,7 @@ public abstract class VideoPlayer extends BasePlayer controlViewAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(final Animator animation) { - controlAnimationView.setVisibility(View.GONE); + binding.controlAnimationView.setVisibility(View.GONE); } }); controlViewAnimator.start(); @@ -923,7 +888,8 @@ public abstract class VideoPlayer extends BasePlayer final float alphaTo = goneOnEnd ? 0f : 1f; - controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder(controlAnimationView, + controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder( + binding.controlAnimationView, PropertyValuesHolder.ofFloat(View.ALPHA, alphaFrom, alphaTo), PropertyValuesHolder.ofFloat(View.SCALE_X, scaleFrom, scaleTo), PropertyValuesHolder.ofFloat(View.SCALE_Y, scaleFrom, scaleTo) @@ -932,17 +898,14 @@ public abstract class VideoPlayer extends BasePlayer controlViewAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(final Animator animation) { - if (goneOnEnd) { - controlAnimationView.setVisibility(View.GONE); - } else { - controlAnimationView.setVisibility(View.VISIBLE); - } + binding.controlAnimationView.setVisibility(goneOnEnd ? View.GONE + : View.VISIBLE); } }); - - controlAnimationView.setVisibility(View.VISIBLE); - controlAnimationView.setImageDrawable(AppCompatResources.getDrawable(context, drawableId)); + binding.controlAnimationView.setVisibility(View.VISIBLE); + binding.controlAnimationView.setImageDrawable(AppCompatResources.getDrawable(context, + drawableId)); controlViewAnimator.start(); } @@ -955,12 +918,12 @@ public abstract class VideoPlayer extends BasePlayer Log.d(TAG, "showControlsThenHide() called"); } - final int hideTime = controlsRoot.isInTouchMode() + final int hideTime = binding.playbackControlRoot.isInTouchMode() ? DEFAULT_CONTROLS_HIDE_TIME : DPAD_CONTROLS_HIDE_TIME; showHideShadow(true, DEFAULT_CONTROLS_DURATION, 0); - animateView(controlsRoot, true, DEFAULT_CONTROLS_DURATION, 0, + animateView(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION, 0, () -> hideControls(DEFAULT_CONTROLS_DURATION, hideTime)); } @@ -970,17 +933,18 @@ public abstract class VideoPlayer extends BasePlayer } controlsVisibilityHandler.removeCallbacksAndMessages(null); showHideShadow(true, duration, 0); - animateView(controlsRoot, true, duration); + animateView(binding.playbackControlRoot, true, duration); } public void safeHideControls(final long duration, final long delay) { if (DEBUG) { Log.d(TAG, "safeHideControls() called with: delay = [" + delay + "]"); } - if (rootView.isInTouchMode()) { + if (binding.getRoot().isInTouchMode()) { controlsVisibilityHandler.removeCallbacksAndMessages(null); controlsVisibilityHandler.postDelayed( - () -> animateView(controlsRoot, false, duration), delay); + () -> animateView(binding.playbackControlRoot, false, duration), + delay); } } @@ -991,7 +955,7 @@ public abstract class VideoPlayer extends BasePlayer controlsVisibilityHandler.removeCallbacksAndMessages(null); controlsVisibilityHandler.postDelayed(() -> { showHideShadow(false, duration, 0); - animateView(controlsRoot, false, duration); + animateView(binding.playbackControlRoot, false, duration); }, delay); } @@ -1007,13 +971,13 @@ public abstract class VideoPlayer extends BasePlayer private Runnable hideControlsAndButtonHandler(final long duration, final View videoPlayPause) { return () -> { videoPlayPause.setVisibility(View.INVISIBLE); - animateView(controlsRoot, false, duration); + animateView(binding.playbackControlRoot, false, duration); }; } void showHideShadow(final boolean show, final long duration, final long delay) { - animateView(playerTopShadow, show, duration, delay, null); - animateView(playerBottomShadow, show, duration, delay, null); + animateView(binding.playerTopShadow, show, duration, delay, null); + animateView(binding.playerBottomShadow, show, duration, delay, null); } public abstract void hideSystemUIIfNeeded(); @@ -1032,7 +996,7 @@ public abstract class VideoPlayer extends BasePlayer } public ExpandableSurfaceView getSurfaceView() { - return surfaceView; + return binding.surfaceView; } public boolean wasPlaying() { @@ -1050,83 +1014,23 @@ public abstract class VideoPlayer extends BasePlayer return controlsVisibilityHandler; } + @NonNull public View getRootView() { - return rootView; - } - - public void setRootView(final View rootView) { - this.rootView = rootView; + return binding.getRoot(); } + @NonNull public View getLoadingPanel() { - return loadingPanel; + return binding.loadingPanel; } - public ImageView getEndScreen() { - return endScreen; - } - - public ImageView getControlAnimationView() { - return controlAnimationView; - } - - public View getControlsRoot() { - return controlsRoot; - } - - public View getBottomControlsRoot() { - return bottomControlsRoot; - } - - public SeekBar getPlaybackSeekBar() { - return playbackSeekBar; - } - - public TextView getPlaybackCurrentTime() { - return playbackCurrentTime; - } - - public TextView getPlaybackEndTime() { - return playbackEndTime; - } - - public LinearLayout getTopControlsRoot() { - return topControlsRoot; - } - - public TextView getQualityTextView() { - return qualityTextView; - } - - public PopupMenu getQualityPopupMenu() { - return qualityPopupMenu; - } - - public TextView getPlaybackSpeedTextView() { - return playbackSpeedTextView; - } - - public PopupMenu getPlaybackSpeedPopupMenu() { - return playbackSpeedPopupMenu; - } - - public View getSurfaceForeground() { - return surfaceForeground; + @NonNull + public View getPlaybackControlRoot() { + return binding.playbackControlRoot; } + @NonNull public TextView getCurrentDisplaySeek() { - return currentDisplaySeek; - } - - public SubtitleView getSubtitleView() { - return subtitleView; - } - - public TextView getResizeView() { - return resizeView; - } - - public TextView getCaptionTextView() { - return captionTextView; + return binding.currentDisplaySeek; } } diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index ce40efb5f..a968ddc91 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -77,6 +77,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.nostra13.universalimageloader.core.assist.FailReason; import org.schabi.newpipe.R; +import org.schabi.newpipe.databinding.PlayerBinding; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; @@ -145,45 +146,11 @@ public class VideoPlayerImpl extends VideoPlayer private static final float MAX_GESTURE_LENGTH = 0.75f; - private TextView titleTextView; - private TextView channelTextView; - private RelativeLayout volumeRelativeLayout; - private ProgressBar volumeProgressBar; - private ImageView volumeImageView; - private RelativeLayout brightnessRelativeLayout; - private ProgressBar brightnessProgressBar; - private ImageView brightnessImageView; - private TextView resizingIndicator; - private ImageButton queueButton; - private ImageButton repeatButton; - private ImageButton shuffleButton; - private ImageButton playWithKodi; - private ImageButton openInBrowser; - private ImageButton fullscreenButton; - private ImageButton playerCloseButton; - private ImageButton screenRotationButton; - private ImageButton muteButton; - - private ImageButton playPauseButton; - private ImageButton playPreviousButton; - private ImageButton playNextButton; - - private RelativeLayout queueLayout; - private ImageButton itemsListCloseButton; - private RecyclerView itemsList; private ItemTouchHelper itemTouchHelper; - private RelativeLayout playerOverlays; - private boolean queueVisible; private MainPlayer.PlayerType playerType = MainPlayer.PlayerType.VIDEO; - private ImageButton moreOptionsButton; - private ImageButton shareButton; - - private View primaryControls; - private View secondaryControls; - private int maxGestureLength; private boolean audioOnly = false; @@ -205,7 +172,6 @@ public class VideoPlayerImpl extends VideoPlayer private WindowManager.LayoutParams popupLayoutParams; public WindowManager windowManager; - private View closingOverlayView; private View closeOverlayView; private FloatingActionButton closeOverlayButton; @@ -251,13 +217,13 @@ public class VideoPlayerImpl extends VideoPlayer getRootView().setVisibility(View.VISIBLE); initPopup(); initPopupCloseOverlay(); - playPauseButton.requestFocus(); + binding.playPauseButton.requestFocus(); } else { getRootView().setVisibility(View.VISIBLE); initVideoPlayer(); onQueueClosed(); // Android TV: without it focus will frame the whole player - playPauseButton.requestFocus(); + binding.playPauseButton.requestFocus(); if (simpleExoPlayer.getPlayWhenReady()) { onPlay(); @@ -279,49 +245,14 @@ public class VideoPlayerImpl extends VideoPlayer @SuppressLint("ClickableViewAccessibility") @Override - public void initViews(final View view) { - super.initViews(view); - this.titleTextView = view.findViewById(R.id.titleTextView); - this.channelTextView = view.findViewById(R.id.channelTextView); - this.volumeRelativeLayout = view.findViewById(R.id.volumeRelativeLayout); - this.volumeProgressBar = view.findViewById(R.id.volumeProgressBar); - this.volumeImageView = view.findViewById(R.id.volumeImageView); - this.brightnessRelativeLayout = view.findViewById(R.id.brightnessRelativeLayout); - this.brightnessProgressBar = view.findViewById(R.id.brightnessProgressBar); - this.brightnessImageView = view.findViewById(R.id.brightnessImageView); - this.resizingIndicator = view.findViewById(R.id.resizing_indicator); - this.queueButton = view.findViewById(R.id.queueButton); - this.repeatButton = view.findViewById(R.id.repeatButton); - this.shuffleButton = view.findViewById(R.id.shuffleButton); - this.playWithKodi = view.findViewById(R.id.playWithKodi); - this.openInBrowser = view.findViewById(R.id.openInBrowser); - this.fullscreenButton = view.findViewById(R.id.fullScreenButton); - this.screenRotationButton = view.findViewById(R.id.screenRotationButton); - this.playerCloseButton = view.findViewById(R.id.playerCloseButton); - this.muteButton = view.findViewById(R.id.switchMute); + public void initViews(@NonNull final PlayerBinding binding) { + super.initViews(binding); - this.playPauseButton = view.findViewById(R.id.playPauseButton); - this.playPreviousButton = view.findViewById(R.id.playPreviousButton); - this.playNextButton = view.findViewById(R.id.playNextButton); - - this.moreOptionsButton = view.findViewById(R.id.moreOptionsButton); - this.primaryControls = view.findViewById(R.id.primaryControls); - this.secondaryControls = view.findViewById(R.id.secondaryControls); - this.shareButton = view.findViewById(R.id.share); - - this.queueLayout = view.findViewById(R.id.playQueuePanel); - this.itemsListCloseButton = view.findViewById(R.id.playQueueClose); - this.itemsList = view.findViewById(R.id.playQueue); - - this.playerOverlays = view.findViewById(R.id.player_overlays); - - closingOverlayView = view.findViewById(R.id.closingOverlay); - - titleTextView.setSelected(true); - channelTextView.setSelected(true); + binding.titleTextView.setSelected(true); + binding.channelTextView.setSelected(true); // Prevent hiding of bottom sheet via swipe inside queue - this.itemsList.setNestedScrollingEnabled(false); + binding.playQueue.setNestedScrollingEnabled(false); } @Override @@ -349,58 +280,60 @@ public class VideoPlayerImpl extends VideoPlayer */ private void setupElementsVisibility() { if (popupPlayerSelected()) { - fullscreenButton.setVisibility(View.VISIBLE); - screenRotationButton.setVisibility(View.GONE); - getResizeView().setVisibility(View.GONE); - getRootView().findViewById(R.id.metadataView).setVisibility(View.GONE); - queueButton.setVisibility(View.GONE); - moreOptionsButton.setVisibility(View.GONE); - getTopControlsRoot().setOrientation(LinearLayout.HORIZONTAL); - primaryControls.getLayoutParams().width = LinearLayout.LayoutParams.WRAP_CONTENT; - secondaryControls.setAlpha(1.0f); - secondaryControls.setVisibility(View.VISIBLE); - secondaryControls.setTranslationY(0); - shareButton.setVisibility(View.GONE); - playWithKodi.setVisibility(View.GONE); - openInBrowser.setVisibility(View.GONE); - muteButton.setVisibility(View.GONE); - playerCloseButton.setVisibility(View.GONE); - getTopControlsRoot().bringToFront(); - getTopControlsRoot().setClickable(false); - getTopControlsRoot().setFocusable(false); - getBottomControlsRoot().bringToFront(); + binding.fullScreenButton.setVisibility(View.VISIBLE); + binding.screenRotationButton.setVisibility(View.GONE); + binding.resizeTextView.setVisibility(View.GONE); + binding.metadataView.setVisibility(View.GONE); + binding.queueButton.setVisibility(View.GONE); + binding.moreOptionsButton.setVisibility(View.GONE); + binding.topControls.setOrientation(LinearLayout.HORIZONTAL); + binding.primaryControls.getLayoutParams().width = + LinearLayout.LayoutParams.WRAP_CONTENT; + binding.secondaryControls.setAlpha(1.0f); + binding.secondaryControls.setVisibility(View.VISIBLE); + binding.secondaryControls.setTranslationY(0); + binding.share.setVisibility(View.GONE); + binding.playWithKodi.setVisibility(View.GONE); + binding.openInBrowser.setVisibility(View.GONE); + binding.switchMute.setVisibility(View.GONE); + binding.playerCloseButton.setVisibility(View.GONE); + binding.topControls.bringToFront(); + binding.topControls.setClickable(false); + binding.topControls.setFocusable(false); + binding.bottomControls.bringToFront(); onQueueClosed(); } else { - fullscreenButton.setVisibility(View.GONE); + binding.fullScreenButton.setVisibility(View.GONE); setupScreenRotationButton(); - getResizeView().setVisibility(View.VISIBLE); - getRootView().findViewById(R.id.metadataView).setVisibility(View.VISIBLE); - moreOptionsButton.setVisibility(View.VISIBLE); - getTopControlsRoot().setOrientation(LinearLayout.VERTICAL); - primaryControls.getLayoutParams().width = LinearLayout.LayoutParams.MATCH_PARENT; - secondaryControls.setVisibility(View.INVISIBLE); - moreOptionsButton.setImageDrawable(AppCompatResources.getDrawable(service, + binding.resizeTextView.setVisibility(View.VISIBLE); + binding.metadataView.setVisibility(View.VISIBLE); + binding.moreOptionsButton.setVisibility(View.VISIBLE); + binding.topControls.setOrientation(LinearLayout.VERTICAL); + binding.primaryControls.getLayoutParams().width = + LinearLayout.LayoutParams.MATCH_PARENT; + binding.secondaryControls.setVisibility(View.INVISIBLE); + binding.moreOptionsButton.setImageDrawable(AppCompatResources.getDrawable(service, R.drawable.ic_expand_more_white_24dp)); - shareButton.setVisibility(View.VISIBLE); + binding.share.setVisibility(View.VISIBLE); showHideKodiButton(); - openInBrowser.setVisibility(View.VISIBLE); - muteButton.setVisibility(View.VISIBLE); - playerCloseButton.setVisibility(isFullscreen ? View.GONE : View.VISIBLE); + binding.openInBrowser.setVisibility(View.VISIBLE); + binding.switchMute.setVisibility(View.VISIBLE); + binding.playerCloseButton.setVisibility(isFullscreen ? View.GONE : View.VISIBLE); // Top controls have a large minHeight which is allows to drag the player // down in fullscreen mode (just larger area to make easy to locate by finger) - getTopControlsRoot().setClickable(true); - getTopControlsRoot().setFocusable(true); + binding.topControls.setClickable(true); + binding.topControls.setFocusable(true); } if (!isFullscreen()) { - titleTextView.setVisibility(View.GONE); - channelTextView.setVisibility(View.GONE); + binding.titleTextView.setVisibility(View.GONE); + binding.channelTextView.setVisibility(View.GONE); } else { - titleTextView.setVisibility(View.VISIBLE); - channelTextView.setVisibility(View.VISIBLE); + binding.titleTextView.setVisibility(View.VISIBLE); + binding.channelTextView.setVisibility(View.VISIBLE); } - setMuteButton(muteButton, isMuted()); + setMuteButton(binding.switchMute, isMuted()); - animateRotation(moreOptionsButton, DEFAULT_CONTROLS_DURATION, 0); + animateRotation(binding.moreOptionsButton, DEFAULT_CONTROLS_DURATION, 0); } /** @@ -413,15 +346,15 @@ public class VideoPlayerImpl extends VideoPlayer .getDimensionPixelSize(R.dimen.player_popup_controls_padding); final int buttonsPadding = service.getResources() .getDimensionPixelSize(R.dimen.player_popup_buttons_padding); - getTopControlsRoot().setPaddingRelative(controlsPadding, 0, controlsPadding, 0); - getBottomControlsRoot().setPaddingRelative(controlsPadding, 0, controlsPadding, 0); - getQualityTextView().setPadding( - buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getPlaybackSpeedTextView().setPadding( - buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getCaptionTextView().setPadding( - buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getPlaybackSpeedTextView().setMinimumWidth(0); + binding.topControls.setPaddingRelative(controlsPadding, 0, controlsPadding, 0); + binding.bottomControls.setPaddingRelative(controlsPadding, 0, controlsPadding, 0); + binding.qualityTextView.setPadding(buttonsPadding, buttonsPadding, buttonsPadding, + buttonsPadding); + binding.playbackSpeed.setPadding(buttonsPadding, buttonsPadding, buttonsPadding, + buttonsPadding); + binding.captionTextView.setPadding(buttonsPadding, buttonsPadding, buttonsPadding, + buttonsPadding); + binding.playbackSpeed.setMinimumWidth(0); } else if (videoPlayerSelected()) { final int buttonsMinWidth = service.getResources() .getDimensionPixelSize(R.dimen.player_main_buttons_min_width); @@ -431,16 +364,16 @@ public class VideoPlayerImpl extends VideoPlayer .getDimensionPixelSize(R.dimen.player_main_controls_padding); final int buttonsPadding = service.getResources() .getDimensionPixelSize(R.dimen.player_main_buttons_padding); - getTopControlsRoot().setPaddingRelative( - controlsPadding, playerTopPadding, controlsPadding, 0); - getBottomControlsRoot().setPaddingRelative(controlsPadding, 0, controlsPadding, 0); - getQualityTextView().setPadding( - buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getPlaybackSpeedTextView().setPadding( - buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); - getPlaybackSpeedTextView().setMinimumWidth(buttonsMinWidth); - getCaptionTextView().setPadding( - buttonsPadding, buttonsPadding, buttonsPadding, buttonsPadding); + binding.topControls.setPaddingRelative(controlsPadding, playerTopPadding, + controlsPadding, 0); + binding.bottomControls.setPaddingRelative(controlsPadding, 0, controlsPadding, 0); + binding.qualityTextView.setPadding(buttonsPadding, buttonsPadding, buttonsPadding, + buttonsPadding); + binding.playbackSpeed.setPadding(buttonsPadding, buttonsPadding, buttonsPadding, + buttonsPadding); + binding.playbackSpeed.setMinimumWidth(buttonsMinWidth); + binding.captionTextView.setPadding(buttonsPadding, buttonsPadding, buttonsPadding, + buttonsPadding); } } @@ -452,23 +385,23 @@ public class VideoPlayerImpl extends VideoPlayer gestureDetector = new GestureDetector(context, listener); getRootView().setOnTouchListener(listener); - queueButton.setOnClickListener(this); - repeatButton.setOnClickListener(this); - shuffleButton.setOnClickListener(this); + binding.queueButton.setOnClickListener(this); + binding.repeatButton.setOnClickListener(this); + binding.shuffleButton.setOnClickListener(this); - playPauseButton.setOnClickListener(this); - playPreviousButton.setOnClickListener(this); - playNextButton.setOnClickListener(this); + binding.playPauseButton.setOnClickListener(this); + binding.playPreviousButton.setOnClickListener(this); + binding.playNextButton.setOnClickListener(this); - moreOptionsButton.setOnClickListener(this); - moreOptionsButton.setOnLongClickListener(this); - shareButton.setOnClickListener(this); - fullscreenButton.setOnClickListener(this); - screenRotationButton.setOnClickListener(this); - playWithKodi.setOnClickListener(this); - openInBrowser.setOnClickListener(this); - playerCloseButton.setOnClickListener(this); - muteButton.setOnClickListener(this); + binding.moreOptionsButton.setOnClickListener(this); + binding.moreOptionsButton.setOnLongClickListener(this); + binding.share.setOnClickListener(this); + binding.fullScreenButton.setOnClickListener(this); + binding.screenRotationButton.setOnClickListener(this); + binding.playWithKodi.setOnClickListener(this); + binding.openInBrowser.setOnClickListener(this); + binding.playerCloseButton.setOnClickListener(this); + binding.switchMute.setOnClickListener(this); settingsContentObserver = new ContentObserver(new Handler()) { @Override @@ -481,24 +414,25 @@ public class VideoPlayerImpl extends VideoPlayer settingsContentObserver); getRootView().addOnLayoutChangeListener(this); - ViewCompat.setOnApplyWindowInsetsListener(queueLayout, (view, windowInsets) -> { - final DisplayCutoutCompat cutout = windowInsets.getDisplayCutout(); - if (cutout != null) { - view.setPadding(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(), - cutout.getSafeInsetRight(), cutout.getSafeInsetBottom()); - } - return windowInsets; - }); + ViewCompat.setOnApplyWindowInsetsListener(binding.playQueuePanel, + (view, windowInsets) -> { + final DisplayCutoutCompat cutout = windowInsets.getDisplayCutout(); + if (cutout != null) { + view.setPadding(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(), + cutout.getSafeInsetRight(), cutout.getSafeInsetBottom()); + } + return windowInsets; + }); // PlaybackControlRoot already consumed window insets but we should pass them to // player_overlays too. Without it they will be off-centered - getControlsRoot().addOnLayoutChangeListener((v, left, top, right, bottom, - oldLeft, oldTop, oldRight, oldBottom) -> - playerOverlays.setPadding( - v.getPaddingLeft(), - v.getPaddingTop(), - v.getPaddingRight(), - v.getPaddingBottom())); + binding.playbackControlRoot.addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> + binding.playerOverlays.setPadding( + v.getPaddingLeft(), + v.getPaddingTop(), + v.getPaddingRight(), + v.getPaddingBottom())); } public boolean onKeyDown(final int keyCode) { @@ -521,7 +455,7 @@ public class VideoPlayerImpl extends VideoPlayer case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_CENTER: - if (getRootView().hasFocus() && !getControlsRoot().hasFocus()) { + if (getRootView().hasFocus() && !binding.playbackControlRoot.hasFocus()) { // do not interfere with focus in playlist etc. return false; } @@ -532,7 +466,7 @@ public class VideoPlayerImpl extends VideoPlayer if (!isControlsVisible()) { if (!queueVisible) { - playPauseButton.requestFocus(); + binding.playPauseButton.requestFocus(); } showControlsThenHide(); showSystemUIPartially(); @@ -548,13 +482,12 @@ public class VideoPlayerImpl extends VideoPlayer public AppCompatActivity getParentActivity() { // ! instanceof ViewGroup means that view was added via windowManager for Popup - if (getRootView() == null - || getRootView().getParent() == null - || !(getRootView().getParent() instanceof ViewGroup)) { + if (binding == null || binding.getRoot().getParent() == null + || !(binding.getRoot().getParent() instanceof ViewGroup)) { return null; } - final ViewGroup parent = (ViewGroup) getRootView().getParent(); + final ViewGroup parent = (ViewGroup) binding.getRoot().getParent(); return (AppCompatActivity) parent.getContext(); } @@ -644,13 +577,14 @@ public class VideoPlayerImpl extends VideoPlayer NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, true); } + @Override protected void onMetadataChanged(@NonNull final MediaSourceTag tag) { super.onMetadataChanged(tag); showHideKodiButton(); - titleTextView.setText(tag.getMetadata().getName()); - channelTextView.setText(tag.getMetadata().getUploaderName()); + binding.titleTextView.setText(tag.getMetadata().getName()); + binding.channelTextView.setText(tag.getMetadata().getUploaderName()); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); updateMetadata(); @@ -668,7 +602,7 @@ public class VideoPlayerImpl extends VideoPlayer public void onMuteUnmuteButtonClicked() { super.onMuteUnmuteButtonClicked(); updatePlayback(); - setMuteButton(muteButton, isMuted()); + setMuteButton(binding.switchMute, isMuted()); } @Override @@ -747,7 +681,7 @@ public class VideoPlayerImpl extends VideoPlayer if (!isFullscreen) { // Apply window insets because Android will not do it when orientation changes // from landscape to portrait (open vertical video to reproduce) - getControlsRoot().setPadding(0, 0, 0, 0); + getPlaybackControlRoot().setPadding(0, 0, 0, 0); } else { // Android needs tens milliseconds to send new insets but a user is able to see // how controls changes it's position from `0` to `nav bar height` padding. @@ -757,13 +691,14 @@ public class VideoPlayerImpl extends VideoPlayer fragmentListener.onFullscreenStateChanged(isFullscreen()); if (!isFullscreen()) { - titleTextView.setVisibility(View.GONE); - channelTextView.setVisibility(View.GONE); - playerCloseButton.setVisibility(videoPlayerSelected() ? View.VISIBLE : View.GONE); + binding.titleTextView.setVisibility(View.GONE); + binding.channelTextView.setVisibility(View.GONE); + binding.playerCloseButton.setVisibility(videoPlayerSelected() + ? View.VISIBLE : View.GONE); } else { - titleTextView.setVisibility(View.VISIBLE); - channelTextView.setVisibility(View.VISIBLE); - playerCloseButton.setVisibility(View.GONE); + binding.titleTextView.setVisibility(View.VISIBLE); + binding.channelTextView.setVisibility(View.VISIBLE); + binding.playerCloseButton.setVisibility(View.GONE); } setupScreenRotationButton(); } @@ -771,34 +706,34 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onClick(final View v) { super.onClick(v); - if (v.getId() == playPauseButton.getId()) { + if (v.getId() == binding.playPauseButton.getId()) { onPlayPause(); - } else if (v.getId() == playPreviousButton.getId()) { + } else if (v.getId() == binding.playPreviousButton.getId()) { onPlayPrevious(); - } else if (v.getId() == playNextButton.getId()) { + } else if (v.getId() == binding.playNextButton.getId()) { onPlayNext(); - } else if (v.getId() == queueButton.getId()) { + } else if (v.getId() == binding.queueButton.getId()) { onQueueClicked(); return; - } else if (v.getId() == repeatButton.getId()) { + } else if (v.getId() == binding.repeatButton.getId()) { onRepeatClicked(); return; - } else if (v.getId() == shuffleButton.getId()) { + } else if (v.getId() == binding.shuffleButton.getId()) { onShuffleClicked(); return; - } else if (v.getId() == moreOptionsButton.getId()) { + } else if (v.getId() == binding.moreOptionsButton.getId()) { onMoreOptionsClicked(); - } else if (v.getId() == shareButton.getId()) { + } else if (v.getId() == binding.share.getId()) { onShareClicked(); - } else if (v.getId() == playWithKodi.getId()) { + } else if (v.getId() == binding.playWithKodi.getId()) { onPlayWithKodiClicked(); - } else if (v.getId() == openInBrowser.getId()) { + } else if (v.getId() == binding.openInBrowser.getId()) { onOpenInBrowserClicked(); - } else if (v.getId() == fullscreenButton.getId()) { + } else if (v.getId() == binding.fullScreenButton.getId()) { setRecovery(); NavigationHelper.playOnMainPlayer(context, getPlayQueue(), true); return; - } else if (v.getId() == screenRotationButton.getId()) { + } else if (v.getId() == binding.screenRotationButton.getId()) { // Only if it's not a vertical video or vertical video but in landscape with locked // orientation a screen orientation can be changed automatically if (!isVerticalVideo @@ -807,32 +742,34 @@ public class VideoPlayerImpl extends VideoPlayer } else { toggleFullscreen(); } - } else if (v.getId() == muteButton.getId()) { + } else if (v.getId() == binding.switchMute.getId()) { onMuteUnmuteButtonClicked(); - } else if (v.getId() == playerCloseButton.getId()) { + } else if (v.getId() == binding.playerCloseButton.getId()) { service.sendBroadcast(new Intent(VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER)); } if (getCurrentState() != STATE_COMPLETED) { getControlsVisibilityHandler().removeCallbacksAndMessages(null); showHideShadow(true, DEFAULT_CONTROLS_DURATION, 0); - animateView(getControlsRoot(), true, DEFAULT_CONTROLS_DURATION, 0, () -> { - if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) { - if (v.getId() == playPauseButton.getId() - // Hide controls in fullscreen immediately - || (v.getId() == screenRotationButton.getId() && isFullscreen)) { - hideControls(0, 0); - } else { - hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); - } - } - }); + animateView(binding.playbackControlRoot, true, DEFAULT_CONTROLS_DURATION, 0, + () -> { + if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) { + if (v.getId() == binding.playPauseButton.getId() + // Hide controls in fullscreen immediately + || (v.getId() == binding.screenRotationButton.getId() + && isFullscreen)) { + hideControls(0, 0); + } else { + hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); + } + } + }); } } @Override public boolean onLongClick(final View v) { - if (v.getId() == moreOptionsButton.getId() && isFullscreen()) { + if (v.getId() == binding.moreOptionsButton.getId() && isFullscreen()) { fragmentListener.onMoreOptionsLongClicked(); hideControls(0, 0); hideSystemUIIfNeeded(); @@ -848,11 +785,11 @@ public class VideoPlayerImpl extends VideoPlayer updatePlaybackButtons(); hideControls(0, 0); - queueLayout.requestFocus(); - animateView(queueLayout, SLIDE_AND_ALPHA, true, + binding.playQueuePanel.requestFocus(); + animateView(binding.playQueuePanel, SLIDE_AND_ALPHA, true, DEFAULT_CONTROLS_DURATION); - itemsList.scrollToPosition(playQueue.getIndex()); + binding.playQueue.scrollToPosition(playQueue.getIndex()); } public void onQueueClosed() { @@ -860,14 +797,15 @@ public class VideoPlayerImpl extends VideoPlayer return; } - animateView(queueLayout, SLIDE_AND_ALPHA, false, + animateView(binding.playQueuePanel, SLIDE_AND_ALPHA, false, DEFAULT_CONTROLS_DURATION, 0, () -> { // Even when queueLayout is GONE it receives touch events // and ruins normal behavior of the app. This line fixes it - queueLayout.setTranslationY(-queueLayout.getHeight() * 5); + binding.playQueuePanel + .setTranslationY(-binding.playQueuePanel.getHeight() * 5); }); queueVisible = false; - playPauseButton.requestFocus(); + binding.playPauseButton.requestFocus(); } private void onMoreOptionsClicked() { @@ -875,18 +813,19 @@ public class VideoPlayerImpl extends VideoPlayer Log.d(TAG, "onMoreOptionsClicked() called"); } - final boolean isMoreControlsVisible = secondaryControls.getVisibility() == View.VISIBLE; + final boolean isMoreControlsVisible = + binding.secondaryControls.getVisibility() == View.VISIBLE; - animateRotation(moreOptionsButton, DEFAULT_CONTROLS_DURATION, + animateRotation(binding.moreOptionsButton, DEFAULT_CONTROLS_DURATION, isMoreControlsVisible ? 0 : 180); - animateView(secondaryControls, SLIDE_AND_ALPHA, !isMoreControlsVisible, + animateView(binding.secondaryControls, SLIDE_AND_ALPHA, !isMoreControlsVisible, DEFAULT_CONTROLS_DURATION, 0, () -> { // Fix for a ripple effect on background drawable. // When view returns from GONE state it takes more milliseconds than returning // from INVISIBLE state. And the delay makes ripple background end to fast if (isMoreControlsVisible) { - secondaryControls.setVisibility(View.INVISIBLE); + binding.secondaryControls.setVisibility(View.INVISIBLE); } }); showControls(DEFAULT_CONTROLS_DURATION); @@ -896,7 +835,7 @@ public class VideoPlayerImpl extends VideoPlayer // share video at the current time (youtube.com/watch?v=ID&t=SECONDS) // Timestamp doesn't make sense in a live stream so drop it - final int ts = getPlaybackSeekBar().getProgress() / 1000; + final int ts = playbackSeekBar.getProgress() / 1000; final MediaSourceTag metadata = getCurrentMetadata(); String videoUrl = getVideoUrl(); if (!isLive() && ts >= 0 && metadata != null @@ -938,18 +877,18 @@ public class VideoPlayerImpl extends VideoPlayer // show kodi button if it supports the current service and it is enabled in settings final boolean showKodiButton = playQueue != null && playQueue.getItem() != null && KoreUtil.shouldShowPlayWithKodi(context, playQueue.getItem().getServiceId()); - playWithKodi.setVisibility(videoPlayerSelected() && kodiEnabled && showKodiButton - ? View.VISIBLE : View.GONE); + binding.playWithKodi.setVisibility(videoPlayerSelected() && kodiEnabled + && showKodiButton ? View.VISIBLE : View.GONE); } private void setupScreenRotationButton() { final boolean orientationLocked = PlayerHelper.globalScreenOrientationLocked(service); final boolean showButton = videoPlayerSelected() && (orientationLocked || isVerticalVideo || DeviceUtils.isTablet(service)); - screenRotationButton.setVisibility(showButton ? View.VISIBLE : View.GONE); - screenRotationButton.setImageDrawable(AppCompatResources.getDrawable(service, isFullscreen() - ? R.drawable.ic_fullscreen_exit_white_24dp - : R.drawable.ic_fullscreen_white_24dp)); + binding.screenRotationButton.setVisibility(showButton ? View.VISIBLE : View.GONE); + binding.screenRotationButton.setImageDrawable(AppCompatResources.getDrawable(service, + isFullscreen() ? R.drawable.ic_fullscreen_exit_white_24dp + : R.drawable.ic_fullscreen_white_24dp)); } private void prepareOrientation() { @@ -1009,11 +948,12 @@ public class VideoPlayerImpl extends VideoPlayer Log.d(TAG, "maxGestureLength = " + maxGestureLength); } - volumeProgressBar.setMax(maxGestureLength); - brightnessProgressBar.setMax(maxGestureLength); + binding.volumeProgressBar.setMax(maxGestureLength); + binding.brightnessProgressBar.setMax(maxGestureLength); setInitialGestureValues(); - queueLayout.getLayoutParams().height = height - queueLayout.getTop(); + binding.playQueuePanel.getLayoutParams().height = height + - binding.playQueuePanel.getTop(); } } @@ -1073,7 +1013,8 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ private void animatePlayButtons(final boolean show, final int duration) { - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, duration); + animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, show, + duration); boolean showQueueButtons = show; if (playQueue == null) { @@ -1082,19 +1023,18 @@ public class VideoPlayerImpl extends VideoPlayer if (!showQueueButtons || playQueue.getIndex() > 0) { animateView( - playPreviousButton, + binding.playPreviousButton, AnimationUtils.Type.SCALE_AND_ALPHA, showQueueButtons, duration); } if (!showQueueButtons || playQueue.getIndex() + 1 < playQueue.getStreams().size()) { animateView( - playNextButton, + binding.playNextButton, AnimationUtils.Type.SCALE_AND_ALPHA, showQueueButtons, duration); } - } @Override @@ -1106,7 +1046,7 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onBlocked() { super.onBlocked(); - playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp); + binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp); animatePlayButtons(false, 100); getRootView().setKeepScreenOn(false); @@ -1126,13 +1066,14 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onPlaying() { super.onPlaying(); - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> { - playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp); - animatePlayButtons(true, 200); - if (!queueVisible) { - playPauseButton.requestFocus(); - } - }); + animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, + 80, 0, () -> { + binding.playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp); + animatePlayButtons(true, 200); + if (!queueVisible) { + binding.playPauseButton.requestFocus(); + } + }); updateWindowFlags(ONGOING_PLAYBACK_WINDOW_FLAGS); checkLandscape(); @@ -1144,13 +1085,15 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onPaused() { super.onPaused(); - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> { - playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp); - animatePlayButtons(true, 200); - if (!queueVisible) { - playPauseButton.requestFocus(); - } - }); + animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, + false, 80, 0, () -> { + binding.playPauseButton + .setImageResource(R.drawable.ic_play_arrow_white_24dp); + animatePlayButtons(true, 200); + if (!queueVisible) { + binding.playPauseButton.requestFocus(); + } + }); updateWindowFlags(IDLE_WINDOW_FLAGS); @@ -1177,10 +1120,11 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void onCompleted() { - animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, () -> { - playPauseButton.setImageResource(R.drawable.ic_replay_white_24dp); - animatePlayButtons(true, DEFAULT_CONTROLS_DURATION); - }); + animateView(binding.playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, + 0, 0, () -> { + binding.playPauseButton.setImageResource(R.drawable.ic_replay_white_24dp); + animatePlayButtons(true, DEFAULT_CONTROLS_DURATION); + }); getRootView().setKeepScreenOn(false); updateWindowFlags(IDLE_WINDOW_FLAGS); @@ -1355,8 +1299,8 @@ public class VideoPlayerImpl extends VideoPlayer if (getAudioReactor() != null) { final float currentVolumeNormalized = (float) getAudioReactor() .getVolume() / getAudioReactor().getMaxVolume(); - volumeProgressBar.setProgress( - (int) (volumeProgressBar.getMax() * currentVolumeNormalized)); + binding.volumeProgressBar.setProgress( + (int) (binding.volumeProgressBar.getMax() * currentVolumeNormalized)); } } @@ -1453,14 +1397,15 @@ public class VideoPlayerImpl extends VideoPlayer getControlsVisibilityHandler().removeCallbacksAndMessages(null); getControlsVisibilityHandler().postDelayed(() -> { showHideShadow(false, duration, 0); - animateView(getControlsRoot(), false, duration, 0, this::hideSystemUIIfNeeded); + animateView(binding.playbackControlRoot, false, duration, 0, + this::hideSystemUIIfNeeded); }, delay ); } @Override public void safeHideControls(final long duration, final long delay) { - if (getControlsRoot().isInTouchMode()) { + if (binding.playbackControlRoot.isInTouchMode()) { hideControls(duration, delay); } } @@ -1474,12 +1419,12 @@ public class VideoPlayerImpl extends VideoPlayer final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size(); final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected(); - playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE); - playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f); - playNextButton.setVisibility(showNext ? View.VISIBLE : View.INVISIBLE); - playNextButton.setAlpha(showNext ? 1.0f : 0.0f); - queueButton.setVisibility(showQueue ? View.VISIBLE : View.GONE); - queueButton.setAlpha(showQueue ? 1.0f : 0.0f); + binding.playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE); + binding.playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f); + binding.playNextButton.setVisibility(showNext ? View.VISIBLE : View.INVISIBLE); + binding.playNextButton.setAlpha(showNext ? 1.0f : 0.0f); + binding.queueButton.setVisibility(showQueue ? View.VISIBLE : View.GONE); + binding.queueButton.setAlpha(showQueue ? 1.0f : 0.0f); } private void showSystemUIPartially() { @@ -1524,15 +1469,12 @@ public class VideoPlayerImpl extends VideoPlayer } private void updatePlaybackButtons() { - if (repeatButton == null - || shuffleButton == null - || simpleExoPlayer == null - || playQueue == null) { + if (binding == null || simpleExoPlayer == null || playQueue == null) { return; } - setRepeatModeButton(repeatButton, getRepeatMode()); - setShuffleButton(shuffleButton, playQueue.isShuffled()); + setRepeatModeButton(binding.repeatButton, getRepeatMode()); + setShuffleButton(binding.shuffleButton, playQueue.isShuffled()); } public void checkLandscape() { @@ -1553,19 +1495,19 @@ public class VideoPlayerImpl extends VideoPlayer } private void buildQueue() { - itemsList.setAdapter(playQueueAdapter); - itemsList.setClickable(true); - itemsList.setLongClickable(true); + binding.playQueue.setAdapter(playQueueAdapter); + binding.playQueue.setClickable(true); + binding.playQueue.setLongClickable(true); - itemsList.clearOnScrollListeners(); - itemsList.addOnScrollListener(getQueueScrollListener()); + binding.playQueue.clearOnScrollListeners(); + binding.playQueue.addOnScrollListener(getQueueScrollListener()); itemTouchHelper = new ItemTouchHelper(getItemTouchCallback()); - itemTouchHelper.attachToRecyclerView(itemsList); + itemTouchHelper.attachToRecyclerView(binding.playQueue); playQueueAdapter.setSelectedListener(getOnSelectedListener()); - itemsListCloseButton.setOnClickListener(view -> onQueueClosed()); + binding.playQueueClose.setOnClickListener(view -> onQueueClosed()); } public void useVideoSource(final boolean video) { @@ -1589,8 +1531,8 @@ public class VideoPlayerImpl extends VideoPlayer public void onScrolledDown(final RecyclerView recyclerView) { if (playQueue != null && !playQueue.isComplete()) { playQueue.fetch(); - } else if (itemsList != null) { - itemsList.clearOnScrollListeners(); + } else if (binding != null) { + binding.playQueue.clearOnScrollListeners(); } } }; @@ -1682,8 +1624,8 @@ public class VideoPlayerImpl extends VideoPlayer checkPopupPositionBounds(); - getLoadingPanel().setMinimumWidth(popupLayoutParams.width); - getLoadingPanel().setMinimumHeight(popupLayoutParams.height); + binding.loadingPanel.setMinimumWidth(popupLayoutParams.width); + binding.loadingPanel.setMinimumHeight(popupLayoutParams.height); service.removeViewFromParent(); windowManager.addView(getRootView(), popupLayoutParams); @@ -1933,10 +1875,9 @@ public class VideoPlayerImpl extends VideoPlayer } private boolean popupHasParent() { - final View root = getRootView(); - return root != null - && root.getLayoutParams() instanceof WindowManager.LayoutParams - && root.getParent() != null; + return binding != null + && binding.getRoot().getLayoutParams() instanceof WindowManager.LayoutParams + && binding.getRoot().getParent() != null; } /////////////////////////////////////////////////////////////////////////// @@ -1949,9 +1890,9 @@ public class VideoPlayerImpl extends VideoPlayer // Apply window insets because Android will not do it when orientation changes // from landscape to portrait if (!isFullscreen) { - getControlsRoot().setPadding(0, 0, 0, 0); + binding.playbackControlRoot.setPadding(0, 0, 0, 0); } - queueLayout.setPadding(0, 0, 0, 0); + binding.playQueuePanel.setPadding(0, 0, 0, 0); updateQueue(); updateMetadata(); updatePlayback(); @@ -2050,31 +1991,31 @@ public class VideoPlayerImpl extends VideoPlayer /////////////////////////////////////////////////////////////////////////// public RelativeLayout getVolumeRelativeLayout() { - return volumeRelativeLayout; + return binding.volumeRelativeLayout; } public ProgressBar getVolumeProgressBar() { - return volumeProgressBar; + return binding.volumeProgressBar; } public ImageView getVolumeImageView() { - return volumeImageView; + return binding.volumeImageView; } public RelativeLayout getBrightnessRelativeLayout() { - return brightnessRelativeLayout; + return binding.brightnessRelativeLayout; } public ProgressBar getBrightnessProgressBar() { - return brightnessProgressBar; + return binding.brightnessProgressBar; } public ImageView getBrightnessImageView() { - return brightnessImageView; + return binding.brightnessImageView; } public ImageButton getPlayPauseButton() { - return playPauseButton; + return binding.playPauseButton; } public int getMaxGestureLength() { @@ -2082,7 +2023,7 @@ public class VideoPlayerImpl extends VideoPlayer } public TextView getResizingIndicator() { - return resizingIndicator; + return binding.resizingIndicator; } public GestureDetector getGestureDetector() { @@ -2125,8 +2066,8 @@ public class VideoPlayerImpl extends VideoPlayer return closeOverlayButton; } - public View getClosingOverlayView() { - return closingOverlayView; + public View getClosingOverlay() { + return binding.closingOverlay; } public boolean isVerticalVideo() { diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java index ab1330f7b..b6916e620 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java @@ -123,7 +123,7 @@ public class PlayerGestureListener } } else /* MainPlayer.PlayerType.POPUP */ { - final View closingOverlayView = playerImpl.getClosingOverlayView(); + final View closingOverlayView = playerImpl.getClosingOverlay(); if (playerImpl.isInsideClosingRadius(movingEvent)) { if (closingOverlayView.getVisibility() == View.GONE) { animateView(closingOverlayView, true, 250); @@ -240,7 +240,7 @@ public class PlayerGestureListener if (playerImpl.isInsideClosingRadius(event)) { playerImpl.closePopup(); } else { - animateView(playerImpl.getClosingOverlayView(), false, 0); + animateView(playerImpl.getClosingOverlay(), false, 0); if (!playerImpl.isPopupClosing) { animateView(playerImpl.getCloseOverlayButton(), false, 200); From fa75c79d34e79e2a71a304bde3e1629d0e1c6194 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Wed, 23 Dec 2020 06:47:36 +0530 Subject: [PATCH 2/2] Use view binding (PlayerPopupCloseOverlayBinding) in VideoPlayerImpl. --- .../newpipe/player/VideoPlayerImpl.java | 48 +++++++++---------- .../player/event/BasePlayerGestureListener.kt | 2 +- .../player/event/PlayerGestureListener.java | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index a968ddc91..949b11374 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -39,6 +39,7 @@ import android.util.TypedValue; import android.view.GestureDetector; import android.view.Gravity; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -73,11 +74,11 @@ import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.text.CaptionStyleCompat; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.SubtitleView; -import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.nostra13.universalimageloader.core.assist.FailReason; import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.PlayerBinding; +import org.schabi.newpipe.databinding.PlayerPopupCloseOverlayBinding; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; @@ -172,8 +173,7 @@ public class VideoPlayerImpl extends VideoPlayer private WindowManager.LayoutParams popupLayoutParams; public WindowManager windowManager; - private View closeOverlayView; - private FloatingActionButton closeOverlayButton; + private PlayerPopupCloseOverlayBinding closeOverlayBinding; public boolean isPopupClosing = false; @@ -1341,10 +1341,10 @@ public class VideoPlayerImpl extends VideoPlayer } private int distanceFromCloseButton(final MotionEvent popupMotionEvent) { - final int closeOverlayButtonX = closeOverlayButton.getLeft() - + closeOverlayButton.getWidth() / 2; - final int closeOverlayButtonY = closeOverlayButton.getTop() - + closeOverlayButton.getHeight() / 2; + final int closeOverlayButtonX = closeOverlayBinding.closeButton.getLeft() + + closeOverlayBinding.closeButton.getWidth() / 2; + final int closeOverlayButtonY = closeOverlayBinding.closeButton.getTop() + + closeOverlayBinding.closeButton.getHeight() / 2; final float fingerX = popupLayoutParams.x + popupMotionEvent.getX(); final float fingerY = popupLayoutParams.y + popupMotionEvent.getY(); @@ -1354,7 +1354,7 @@ public class VideoPlayerImpl extends VideoPlayer } private float getClosingRadius() { - final int buttonRadius = closeOverlayButton.getWidth() / 2; + final int buttonRadius = closeOverlayBinding.closeButton.getWidth() / 2; // 20% wider than the button itself return buttonRadius * 1.2f; } @@ -1641,12 +1641,11 @@ public class VideoPlayerImpl extends VideoPlayer } // closeOverlayView is already added to windowManager - if (closeOverlayView != null) { + if (closeOverlayBinding != null) { return; } - closeOverlayView = View.inflate(service, R.layout.player_popup_close_overlay, null); - closeOverlayButton = closeOverlayView.findViewById(R.id.closeButton); + closeOverlayBinding = PlayerPopupCloseOverlayBinding.inflate(LayoutInflater.from(service)); final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE @@ -1661,8 +1660,8 @@ public class VideoPlayerImpl extends VideoPlayer closeOverlayLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; - closeOverlayButton.setVisibility(View.GONE); - windowManager.addView(closeOverlayView, closeOverlayLayoutParams); + closeOverlayBinding.closeButton.setVisibility(View.GONE); + windowManager.addView(closeOverlayBinding.getRoot(), closeOverlayLayoutParams); } private void initVideoPlayer() { @@ -1835,22 +1834,23 @@ public class VideoPlayerImpl extends VideoPlayer } public void removePopupFromView() { - final boolean isCloseOverlayHasParent = closeOverlayView != null - && closeOverlayView.getParent() != null; + final boolean isCloseOverlayHasParent = closeOverlayBinding != null + && closeOverlayBinding.getRoot().getParent() != null; if (popupHasParent()) { windowManager.removeView(getRootView()); } if (isCloseOverlayHasParent) { - windowManager.removeView(closeOverlayView); + windowManager.removeView(closeOverlayBinding.getRoot()); } } private void animateOverlayAndFinishService() { - final int targetTranslationY = (int) (closeOverlayButton.getRootView().getHeight() - - closeOverlayButton.getY()); + final int targetTranslationY = + (int) (closeOverlayBinding.closeButton.getRootView().getHeight() + - closeOverlayBinding.closeButton.getY()); - closeOverlayButton.animate().setListener(null).cancel(); - closeOverlayButton.animate() + closeOverlayBinding.closeButton.animate().setListener(null).cancel(); + closeOverlayBinding.closeButton.animate() .setInterpolator(new AnticipateInterpolator()) .translationY(targetTranslationY) .setDuration(400) @@ -1866,8 +1866,8 @@ public class VideoPlayerImpl extends VideoPlayer } private void end() { - windowManager.removeView(closeOverlayView); - closeOverlayView = null; + windowManager.removeView(closeOverlayBinding.getRoot()); + closeOverlayBinding = null; service.onDestroy(); } @@ -2062,8 +2062,8 @@ public class VideoPlayerImpl extends VideoPlayer popupHeight = height; } - public View getCloseOverlayButton() { - return closeOverlayButton; + public View getCloseButton() { + return closeOverlayBinding.closeButton; } public View getClosingOverlay() { diff --git a/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt index 043e7f31d..d34746ca5 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt +++ b/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt @@ -371,7 +371,7 @@ abstract class BasePlayerGestureListener( } if (!isMovingInPopup) { - AnimationUtils.animateView(playerImpl.closeOverlayButton, true, 200) + AnimationUtils.animateView(playerImpl.closeButton, true, 200) } isMovingInPopup = true diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java index b6916e620..8f9514781 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java @@ -243,7 +243,7 @@ public class PlayerGestureListener animateView(playerImpl.getClosingOverlay(), false, 0); if (!playerImpl.isPopupClosing) { - animateView(playerImpl.getCloseOverlayButton(), false, 200); + animateView(playerImpl.getCloseButton(), false, 200); } } }