From 69fc571b5618fd66e4d40b5420e49b1c6e6c5a3b Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Tue, 21 Aug 2018 23:04:46 -0300 Subject: [PATCH 1/4] Add overlay to close popup --- .../newpipe/player/PopupVideoPlayer.java | 280 +++++++++++++----- app/src/main/res/layout/player_popup.xml | 8 +- .../res/layout/player_popup_close_overlay.xml | 18 ++ 3 files changed, 231 insertions(+), 75 deletions(-) create mode 100644 app/src/main/res/layout/player_popup_close_overlay.xml diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 86998e0ea..37a9e917e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -19,6 +19,8 @@ package org.schabi.newpipe.player; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; import android.app.NotificationManager; import android.app.PendingIntent; @@ -34,6 +36,7 @@ import android.os.Build; import android.os.IBinder; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.design.widget.FloatingActionButton; import android.support.v4.app.NotificationCompat; import android.util.DisplayMetrics; import android.util.Log; @@ -41,7 +44,9 @@ import android.view.GestureDetector; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.WindowManager; +import android.view.animation.AnticipateInterpolator; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.PopupMenu; @@ -104,8 +109,12 @@ public final class PopupVideoPlayer extends Service { WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; private WindowManager windowManager; - private WindowManager.LayoutParams windowLayoutParams; - private GestureDetector gestureDetector; + private WindowManager.LayoutParams popupLayoutParams; + private GestureDetector popupGestureDetector; + + private View closeOverlayView; + private FloatingActionButton closeOverlayButton; + private WindowManager.LayoutParams closeOverlayLayoutParams; private int shutdownFlingVelocity; private int tossFlingVelocity; @@ -122,6 +131,7 @@ public final class PopupVideoPlayer extends Service { private VideoPlayerImpl playerImpl; private LockManager lockManager; + private boolean isPopupClosing = false; /*////////////////////////////////////////////////////////////////////////// // Service-Activity Binder @@ -150,7 +160,10 @@ public final class PopupVideoPlayer extends Service { public int onStartCommand(final Intent intent, int flags, int startId) { if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]"); - if (playerImpl.getPlayer() == null) initPopup(); + if (playerImpl.getPlayer() == null) { + initPopup(); + initPopupCloseOverlay(); + } if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true); playerImpl.handleIntent(intent); @@ -160,15 +173,16 @@ public final class PopupVideoPlayer extends Service { @Override public void onConfigurationChanged(Configuration newConfig) { + if (DEBUG) Log.d(TAG, "onConfigurationChanged() called with: newConfig = [" + newConfig + "]"); updateScreenSize(); - updatePopupSize(windowLayoutParams.width, -1); + updatePopupSize(popupLayoutParams.width, -1); checkPositionBounds(); } @Override public void onDestroy() { if (DEBUG) Log.d(TAG, "onDestroy() called"); - onClose(); + closePopup(); } @Override @@ -200,27 +214,52 @@ public final class PopupVideoPlayer extends Service { WindowManager.LayoutParams.TYPE_PHONE : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; - windowLayoutParams = new WindowManager.LayoutParams( + popupLayoutParams = new WindowManager.LayoutParams( (int) popupWidth, (int) getMinimumVideoHeight(popupWidth), layoutParamType, IDLE_WINDOW_FLAGS, PixelFormat.TRANSLUCENT); - windowLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; - windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + popupLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; + popupLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; int centerX = (int) (screenWidth / 2f - popupWidth / 2f); int centerY = (int) (screenHeight / 2f - popupHeight / 2f); - windowLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; - windowLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; + popupLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; + popupLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; checkPositionBounds(); - MySimpleOnGestureListener listener = new MySimpleOnGestureListener(); - gestureDetector = new GestureDetector(this, listener); + PopupWindowGestureListener listener = new PopupWindowGestureListener(); + popupGestureDetector = new GestureDetector(this, listener); rootView.setOnTouchListener(listener); - playerImpl.getLoadingPanel().setMinimumWidth(windowLayoutParams.width); - playerImpl.getLoadingPanel().setMinimumHeight(windowLayoutParams.height); - windowManager.addView(rootView, windowLayoutParams); + + playerImpl.getLoadingPanel().setMinimumWidth(popupLayoutParams.width); + playerImpl.getLoadingPanel().setMinimumHeight(popupLayoutParams.height); + windowManager.addView(rootView, popupLayoutParams); + } + + @SuppressLint("RtlHardcoded") + private void initPopupCloseOverlay() { + if (DEBUG) Log.d(TAG, "initPopupCloseOverlay() called"); + closeOverlayView = View.inflate(this, R.layout.player_popup_close_overlay, null); + closeOverlayButton = closeOverlayView.findViewById(R.id.closeButton); + + final int layoutParamType = Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? + WindowManager.LayoutParams.TYPE_PHONE : + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + + closeOverlayLayoutParams = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, + layoutParamType, + flags, + PixelFormat.TRANSLUCENT); + closeOverlayLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; + closeOverlayLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; + + closeOverlayButton.setVisibility(View.GONE); + windowManager.addView(closeOverlayView, closeOverlayLayoutParams); } /*////////////////////////////////////////////////////////////////////////// @@ -280,24 +319,54 @@ public final class PopupVideoPlayer extends Service { // Misc //////////////////////////////////////////////////////////////////////////*/ - public void onClose() { - if (DEBUG) Log.d(TAG, "onClose() called"); + public void closePopup() { + if (DEBUG) Log.d(TAG, "closePopup() called, isPopupClosing = " + isPopupClosing); + if (isPopupClosing) return; + isPopupClosing = true; if (playerImpl != null) { if (playerImpl.getRootView() != null) { windowManager.removeView(playerImpl.getRootView()); - playerImpl.setRootView(null); } + playerImpl.setRootView(null); playerImpl.stopActivityBinding(); playerImpl.destroy(); + playerImpl = null; } + + mBinder = null; if (lockManager != null) lockManager.releaseWifiAndCpu(); if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID); - mBinder = null; - playerImpl = null; - stopForeground(true); - stopSelf(); + animateOverlayAndFinishService(); + } + + private void animateOverlayAndFinishService() { + final int targetTranslationY = (int) (closeOverlayButton.getRootView().getHeight() - closeOverlayButton.getY()); + + closeOverlayButton.animate().setListener(null).cancel(); + closeOverlayButton.animate() + .setInterpolator(new AnticipateInterpolator()) + .translationY(targetTranslationY) + .setDuration(400) + .setListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + end(); + } + + @Override + public void onAnimationEnd(Animator animation) { + end(); + } + + private void end() { + windowManager.removeView(closeOverlayView); + + stopForeground(true); + stopSelf(); + } + }).start(); } /*////////////////////////////////////////////////////////////////////////// @@ -305,19 +374,21 @@ public final class PopupVideoPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ private void checkPositionBounds() { - if (windowLayoutParams.x > screenWidth - windowLayoutParams.width) - windowLayoutParams.x = (int) (screenWidth - windowLayoutParams.width); - if (windowLayoutParams.x < 0) windowLayoutParams.x = 0; - if (windowLayoutParams.y > screenHeight - windowLayoutParams.height) - windowLayoutParams.y = (int) (screenHeight - windowLayoutParams.height); - if (windowLayoutParams.y < 0) windowLayoutParams.y = 0; + if (DEBUG) Log.d(TAG, "checkPositionBounds() called"); + if (popupLayoutParams.x > screenWidth - popupLayoutParams.width) + popupLayoutParams.x = (int) (screenWidth - popupLayoutParams.width); + if (popupLayoutParams.x < 0) popupLayoutParams.x = 0; + + if (popupLayoutParams.y > screenHeight - popupLayoutParams.height) + popupLayoutParams.y = (int) (screenHeight - popupLayoutParams.height); + if (popupLayoutParams.y < 0) popupLayoutParams.y = 0; } private void savePositionAndSize() { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PopupVideoPlayer.this); - sharedPreferences.edit().putInt(POPUP_SAVED_X, windowLayoutParams.x).apply(); - sharedPreferences.edit().putInt(POPUP_SAVED_Y, windowLayoutParams.y).apply(); - sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, windowLayoutParams.width).apply(); + sharedPreferences.edit().putInt(POPUP_SAVED_X, popupLayoutParams.x).apply(); + sharedPreferences.edit().putInt(POPUP_SAVED_Y, popupLayoutParams.y).apply(); + sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, popupLayoutParams.width).apply(); } private float getMinimumVideoHeight(float width) { @@ -352,13 +423,13 @@ public final class PopupVideoPlayer extends Service { if (height == -1) height = (int) getMinimumVideoHeight(width); else height = (int) (height > maximumHeight ? maximumHeight : height < minimumHeight ? minimumHeight : height); - windowLayoutParams.width = width; - windowLayoutParams.height = height; + popupLayoutParams.width = width; + popupLayoutParams.height = height; popupWidth = width; popupHeight = height; if (DEBUG) Log.d(TAG, "updatePopupSize() updated values: width = [" + width + "], height = [" + height + "]"); - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); } protected void setRepeatModeRemote(final RemoteViews remoteViews, final int repeatMode) { @@ -380,10 +451,10 @@ public final class PopupVideoPlayer extends Service { } private void updateWindowFlags(final int flags) { - if (windowLayoutParams == null || windowManager == null || playerImpl == null) return; + if (popupLayoutParams == null || windowManager == null || playerImpl == null) return; - windowLayoutParams.flags = flags; - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + popupLayoutParams.flags = flags; + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); } /////////////////////////////////////////////////////////////////////////// @@ -393,6 +464,7 @@ public final class PopupVideoPlayer extends Service { private ImageView videoPlayPause; private View extraOptionsView; + private View closingOverlayView; @Override public void handleIntent(Intent intent) { @@ -413,12 +485,18 @@ public final class PopupVideoPlayer extends Service { fullScreenButton = rootView.findViewById(R.id.fullScreenButton); fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked()); videoPlayPause = rootView.findViewById(R.id.videoPlayPause); - videoPlayPause.setOnClickListener(this::onPlayPauseButtonPressed); extraOptionsView = rootView.findViewById(R.id.extraOptionsView); + closingOverlayView = rootView.findViewById(R.id.closingOverlay); rootView.addOnLayoutChangeListener(this); } + @Override + public void initListeners() { + super.initListeners(); + videoPlayPause.setOnClickListener(v -> onPlayPause()); + } + @Override protected void setupSubtitleView(@NonNull SubtitleView view, final float captionScale, @@ -429,10 +507,6 @@ public final class PopupVideoPlayer extends Service { view.setStyle(captionStyle); } - private void onPlayPauseButtonPressed(View ib) { - onPlayPause(); - } - @Override public void onLayoutChange(final View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { @@ -476,7 +550,7 @@ public final class PopupVideoPlayer extends Service { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } context.startActivity(intent); - onClose(); + closePopup(); } @Override @@ -634,7 +708,7 @@ public final class PopupVideoPlayer extends Service { @Override public void onPlaybackShutdown() { super.onPlaybackShutdown(); - onClose(); + closePopup(); } /*////////////////////////////////////////////////////////////////////////// @@ -660,7 +734,7 @@ public final class PopupVideoPlayer extends Service { if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]"); switch (intent.getAction()) { case ACTION_CLOSE: - onClose(); + closePopup(); break; case ACTION_PLAY_PAUSE: onPlayPause(); @@ -791,12 +865,15 @@ public final class PopupVideoPlayer extends Service { public TextView getResizingIndicator() { return resizingIndicator; } + + public View getClosingOverlayView() { + return closingOverlayView; + } } - private class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { + private class PopupWindowGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { private int initialPopupX, initialPopupY; private boolean isMoving; - private boolean isResizing; @Override @@ -832,10 +909,10 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onDown(MotionEvent e) { if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]"); - initialPopupX = windowLayoutParams.x; - initialPopupY = windowLayoutParams.y; - popupWidth = windowLayoutParams.width; - popupHeight = windowLayoutParams.height; + initialPopupX = popupLayoutParams.x; + initialPopupY = popupLayoutParams.y; + popupWidth = popupLayoutParams.width; + popupHeight = popupLayoutParams.height; return super.onDown(e); } @@ -848,15 +925,20 @@ public final class PopupVideoPlayer extends Service { } @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (isResizing || playerImpl == null) return super.onScroll(e1, e2, distanceX, distanceY); + public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { + if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING && (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0); + + if (!isMoving) { + animateView(closeOverlayButton, true, 200); + } + isMoving = true; - float diffX = (int) (e2.getRawX() - e1.getRawX()), posX = (int) (initialPopupX + diffX); - float diffY = (int) (e2.getRawY() - e1.getRawY()), posY = (int) (initialPopupY + diffY); + float diffX = (int) (movingEvent.getRawX() - initialEvent.getRawX()), posX = (int) (initialPopupX + diffX); + float diffY = (int) (movingEvent.getRawY() - initialEvent.getRawY()), posY = (int) (initialPopupY + diffY); if (posX > (screenWidth - popupWidth)) posX = (int) (screenWidth - popupWidth); else if (posX < 0) posX = 0; @@ -864,26 +946,49 @@ public final class PopupVideoPlayer extends Service { if (posY > (screenHeight - popupHeight)) posY = (int) (screenHeight - popupHeight); else if (posY < 0) posY = 0; - windowLayoutParams.x = (int) posX; - windowLayoutParams.y = (int) posY; + popupLayoutParams.x = (int) posX; + popupLayoutParams.y = (int) posY; + + final View closingOverlayView = playerImpl.getClosingOverlayView(); + if (isInsideClosingRadius(movingEvent)) { + if (closingOverlayView.getVisibility() == View.GONE) { + animateView(closingOverlayView, true, 250); + } + } else { + if (closingOverlayView.getVisibility() == View.VISIBLE) { + animateView(closingOverlayView, false, 0); + } + } //noinspection PointlessBooleanExpression - if (DEBUG && false) Log.d(TAG, "PopupVideoPlayer.onScroll = " + - ", e1.getRaw = [" + e1.getRawX() + ", " + e1.getRawY() + "]" + - ", e2.getRaw = [" + e2.getRawX() + ", " + e2.getRawY() + "]" + - ", distanceXy = [" + distanceX + ", " + distanceY + "]" + - ", posXy = [" + posX + ", " + posY + "]" + - ", popupWh = [" + popupWidth + " x " + popupHeight + "]"); - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + if (DEBUG && false) { + Log.d(TAG, "PopupVideoPlayer.onScroll = " + + ", e1.getRaw = [" + initialEvent.getRawX() + ", " + initialEvent.getRawY() + "]" + ", e1.getX,Y = [" + initialEvent.getX() + ", " + initialEvent.getY() + "]" + + ", e2.getRaw = [" + movingEvent.getRawX() + ", " + movingEvent.getRawY() + "]" + ", e2.getX,Y = [" + movingEvent.getX() + ", " + movingEvent.getY() + "]" + + ", distanceX,Y = [" + distanceX + ", " + distanceY + "]" + + ", posX,Y = [" + posX + ", " + posY + "]" + + ", popupW,H = [" + popupWidth + " x " + popupHeight + "]"); + } + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); return true; } - private void onScrollEnd() { + private void onScrollEnd(MotionEvent event) { if (DEBUG) Log.d(TAG, "onScrollEnd() called"); if (playerImpl == null) return; if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) { playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); } + + if (isInsideClosingRadius(event)) { + closePopup(); + } else { + animateView(playerImpl.getClosingOverlayView(), false, 0); + + if (!isPopupClosing) { + animateView(closeOverlayButton, false, 200); + } + } } @Override @@ -894,13 +999,13 @@ public final class PopupVideoPlayer extends Service { final float absVelocityX = Math.abs(velocityX); final float absVelocityY = Math.abs(velocityY); if (absVelocityX > shutdownFlingVelocity) { - onClose(); + closePopup(); return true; } else if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { - if (absVelocityX > tossFlingVelocity) windowLayoutParams.x = (int) velocityX; - if (absVelocityY > tossFlingVelocity) windowLayoutParams.y = (int) velocityY; + if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX; + if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY; checkPositionBounds(); - windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams); + windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); return true; } return false; @@ -908,7 +1013,7 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onTouch(View v, MotionEvent event) { - gestureDetector.onTouchEvent(event); + popupGestureDetector.onTouchEvent(event); if (playerImpl == null) return false; if (event.getPointerCount() == 2 && !isResizing) { if (DEBUG) Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing."); @@ -931,7 +1036,7 @@ public final class PopupVideoPlayer extends Service { Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]"); if (isMoving) { isMoving = false; - onScrollEnd(); + onScrollEnd(event); } if (isResizing) { @@ -939,7 +1044,10 @@ public final class PopupVideoPlayer extends Service { animateView(playerImpl.getResizingIndicator(), false, 100, 0); playerImpl.changeState(playerImpl.getCurrentState()); } - savePositionAndSize(); + + if (!isPopupClosing) { + savePositionAndSize(); + } } v.performClick(); @@ -955,10 +1063,10 @@ public final class PopupVideoPlayer extends Service { final float diff = Math.abs(firstPointerX - secondPointerX); if (firstPointerX > secondPointerX) { // second pointer is the anchor (the leftmost pointer) - windowLayoutParams.x = (int) (event.getRawX() - diff); + popupLayoutParams.x = (int) (event.getRawX() - diff); } else { // first pointer is the anchor - windowLayoutParams.x = (int) event.getRawX(); + popupLayoutParams.x = (int) event.getRawX(); } checkPositionBounds(); @@ -969,5 +1077,29 @@ public final class PopupVideoPlayer extends Service { return true; } + + /*////////////////////////////////////////////////////////////////////////// + // Utils + //////////////////////////////////////////////////////////////////////////*/ + + private int distanceFromCloseButton(MotionEvent popupMotionEvent) { + final int closeOverlayButtonX = closeOverlayButton.getLeft() + closeOverlayButton.getWidth() / 2; + final int closeOverlayButtonY = closeOverlayButton.getTop() + closeOverlayButton.getHeight() / 2; + + float fingerX = popupLayoutParams.x + popupMotionEvent.getX(); + float fingerY = popupLayoutParams.y + popupMotionEvent.getY(); + + return (int) Math.sqrt(Math.pow(closeOverlayButtonX - fingerX, 2) + Math.pow(closeOverlayButtonY - fingerY, 2)); + } + + private float getClosingRadius() { + final int buttonRadius = closeOverlayButton.getWidth() / 2; + // 20% wider than the button itself + return buttonRadius * 1.2f; + } + + private boolean isInsideClosingRadius(MotionEvent popupMotionEvent) { + return distanceFromCloseButton(popupMotionEvent) <= getClosingRadius(); + } } } \ No newline at end of file diff --git a/app/src/main/res/layout/player_popup.xml b/app/src/main/res/layout/player_popup.xml index 001d43bf6..7a92c6712 100644 --- a/app/src/main/res/layout/player_popup.xml +++ b/app/src/main/res/layout/player_popup.xml @@ -9,7 +9,6 @@ tools:layout_height="84dp" tools:layout_width="@dimen/popup_minimum_width"> - + + \ No newline at end of file diff --git a/app/src/main/res/layout/player_popup_close_overlay.xml b/app/src/main/res/layout/player_popup_close_overlay.xml new file mode 100644 index 000000000..f7aceadec --- /dev/null +++ b/app/src/main/res/layout/player_popup_close_overlay.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file From a01d6eaf72fd83b3320d6c6ab23d30550ad828d8 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Tue, 21 Aug 2018 23:04:52 -0300 Subject: [PATCH 2/4] Don't make controls visible when moving popup --- .../main/java/org/schabi/newpipe/player/PopupVideoPlayer.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 37a9e917e..2d943ea11 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -928,9 +928,6 @@ public final class PopupVideoPlayer extends Service { public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) { if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY); - if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING - && (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0); - if (!isMoving) { animateView(closeOverlayButton, true, 200); } From 8a29cfbb7e109a82ba48dc24deacb54729edb4c2 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Tue, 21 Aug 2018 23:04:52 -0300 Subject: [PATCH 3/4] Remove popup shutdown gesture in favor of the new close overlay --- .../java/org/schabi/newpipe/player/PopupVideoPlayer.java | 7 +------ .../org/schabi/newpipe/player/helper/PlayerHelper.java | 4 ---- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 2d943ea11..bf1669e6e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -116,7 +116,6 @@ public final class PopupVideoPlayer extends Service { private FloatingActionButton closeOverlayButton; private WindowManager.LayoutParams closeOverlayLayoutParams; - private int shutdownFlingVelocity; private int tossFlingVelocity; private float screenWidth, screenHeight; @@ -200,7 +199,6 @@ public final class PopupVideoPlayer extends Service { View rootView = View.inflate(this, R.layout.player_popup, null); playerImpl.setup(rootView); - shutdownFlingVelocity = PlayerHelper.getShutdownFlingVelocity(this); tossFlingVelocity = PlayerHelper.getTossFlingVelocity(this); updateScreenSize(); @@ -995,10 +993,7 @@ public final class PopupVideoPlayer extends Service { final float absVelocityX = Math.abs(velocityX); final float absVelocityY = Math.abs(velocityY); - if (absVelocityX > shutdownFlingVelocity) { - closePopup(); - return true; - } else if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { + if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX; if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY; checkPositionBounds(); diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 275f488e3..ae187a834 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -251,10 +251,6 @@ public class PlayerHelper { return true; } - public static int getShutdownFlingVelocity(@NonNull final Context context) { - return 6000; - } - public static int getTossFlingVelocity(@NonNull final Context context) { return 2500; } From 3887231c73bb165790bc1929067743f7457834c1 Mon Sep 17 00:00:00 2001 From: Mauricio Colli Date: Wed, 22 Aug 2018 23:45:25 -0300 Subject: [PATCH 4/4] Fix popup position when draggable area is resized A common case where this happens is when the soft input is visible. --- .../newpipe/player/PopupVideoPlayer.java | 60 +++++++++++++++---- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index bf1669e6e..0e7328020 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -175,7 +175,7 @@ public final class PopupVideoPlayer extends Service { if (DEBUG) Log.d(TAG, "onConfigurationChanged() called with: newConfig = [" + newConfig + "]"); updateScreenSize(); updatePopupSize(popupLayoutParams.width, -1); - checkPositionBounds(); + checkPopupPositionBounds(); } @Override @@ -225,7 +225,7 @@ public final class PopupVideoPlayer extends Service { popupLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; popupLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; - checkPositionBounds(); + checkPopupPositionBounds(); PopupWindowGestureListener listener = new PopupWindowGestureListener(); popupGestureDetector = new GestureDetector(this, listener); @@ -371,15 +371,44 @@ public final class PopupVideoPlayer extends Service { // Utils //////////////////////////////////////////////////////////////////////////*/ - private void checkPositionBounds() { - if (DEBUG) Log.d(TAG, "checkPositionBounds() called"); - if (popupLayoutParams.x > screenWidth - popupLayoutParams.width) - popupLayoutParams.x = (int) (screenWidth - popupLayoutParams.width); - if (popupLayoutParams.x < 0) popupLayoutParams.x = 0; + /** + * @see #checkPopupPositionBounds(float, float) + */ + @SuppressWarnings("UnusedReturnValue") + private boolean checkPopupPositionBounds() { + return checkPopupPositionBounds(screenWidth, screenHeight); + } - if (popupLayoutParams.y > screenHeight - popupLayoutParams.height) - popupLayoutParams.y = (int) (screenHeight - popupLayoutParams.height); - if (popupLayoutParams.y < 0) popupLayoutParams.y = 0; + /** + * Check if {@link #popupLayoutParams}' position is within a arbitrary boundary that goes from (0,0) to (boundaryWidth,boundaryHeight). + *

+ * If it's out of these boundaries, {@link #popupLayoutParams}' position is changed and {@code true} is returned + * to represent this change. + * + * @return if the popup was out of bounds and have been moved back to it + */ + private boolean checkPopupPositionBounds(final float boundaryWidth, final float boundaryHeight) { + if (DEBUG) { + Log.d(TAG, "checkPopupPositionBounds() called with: boundaryWidth = [" + boundaryWidth + "], boundaryHeight = [" + boundaryHeight + "]"); + } + + if (popupLayoutParams.x < 0) { + popupLayoutParams.x = 0; + return true; + } else if (popupLayoutParams.x > boundaryWidth - popupLayoutParams.width) { + popupLayoutParams.x = (int) (boundaryWidth - popupLayoutParams.width); + return true; + } + + if (popupLayoutParams.y < 0) { + popupLayoutParams.y = 0; + return true; + } else if (popupLayoutParams.y > boundaryHeight - popupLayoutParams.height) { + popupLayoutParams.y = (int) (boundaryHeight - popupLayoutParams.height); + return true; + } + + return false; } private void savePositionAndSize() { @@ -907,6 +936,11 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onDown(MotionEvent e) { if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]"); + + // Fix popup position when the user touch it, it may have the wrong one + // because the soft input is visible (the draggable area is currently resized). + checkPopupPositionBounds(closeOverlayView.getWidth(), closeOverlayView.getHeight()); + initialPopupX = popupLayoutParams.x; initialPopupY = popupLayoutParams.y; popupWidth = popupLayoutParams.width; @@ -918,7 +952,7 @@ public final class PopupVideoPlayer extends Service { public void onLongPress(MotionEvent e) { if (DEBUG) Log.d(TAG, "onLongPress() called with: e = [" + e + "]"); updateScreenSize(); - checkPositionBounds(); + checkPopupPositionBounds(); updatePopupSize((int) screenWidth, -1); } @@ -996,7 +1030,7 @@ public final class PopupVideoPlayer extends Service { if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) { if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX; if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY; - checkPositionBounds(); + checkPopupPositionBounds(); windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); return true; } @@ -1061,7 +1095,7 @@ public final class PopupVideoPlayer extends Service { popupLayoutParams.x = (int) event.getRawX(); } - checkPositionBounds(); + checkPopupPositionBounds(); updateScreenSize(); final int width = (int) Math.min(screenWidth, diff);