Merge pull request #1597 from mauriciocolli/close-popup-overlay
New way to close the popup player
This commit is contained in:
commit
78547aa119
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
package org.schabi.newpipe.player;
|
package org.schabi.newpipe.player;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
@ -34,6 +36,7 @@ import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -41,7 +44,9 @@ import android.view.GestureDetector;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.animation.AnticipateInterpolator;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
|
@ -104,10 +109,13 @@ public final class PopupVideoPlayer extends Service {
|
||||||
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||||
|
|
||||||
private WindowManager windowManager;
|
private WindowManager windowManager;
|
||||||
private WindowManager.LayoutParams windowLayoutParams;
|
private WindowManager.LayoutParams popupLayoutParams;
|
||||||
private GestureDetector gestureDetector;
|
private GestureDetector popupGestureDetector;
|
||||||
|
|
||||||
|
private View closeOverlayView;
|
||||||
|
private FloatingActionButton closeOverlayButton;
|
||||||
|
private WindowManager.LayoutParams closeOverlayLayoutParams;
|
||||||
|
|
||||||
private int shutdownFlingVelocity;
|
|
||||||
private int tossFlingVelocity;
|
private int tossFlingVelocity;
|
||||||
|
|
||||||
private float screenWidth, screenHeight;
|
private float screenWidth, screenHeight;
|
||||||
|
@ -122,6 +130,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
|
|
||||||
private VideoPlayerImpl playerImpl;
|
private VideoPlayerImpl playerImpl;
|
||||||
private LockManager lockManager;
|
private LockManager lockManager;
|
||||||
|
private boolean isPopupClosing = false;
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Service-Activity Binder
|
// Service-Activity Binder
|
||||||
|
@ -150,7 +159,10 @@ public final class PopupVideoPlayer extends Service {
|
||||||
public int onStartCommand(final Intent intent, int flags, int startId) {
|
public int onStartCommand(final Intent intent, int flags, int startId) {
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
|
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);
|
if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true);
|
||||||
|
|
||||||
playerImpl.handleIntent(intent);
|
playerImpl.handleIntent(intent);
|
||||||
|
@ -160,15 +172,16 @@ public final class PopupVideoPlayer extends Service {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
if (DEBUG) Log.d(TAG, "onConfigurationChanged() called with: newConfig = [" + newConfig + "]");
|
||||||
updateScreenSize();
|
updateScreenSize();
|
||||||
updatePopupSize(windowLayoutParams.width, -1);
|
updatePopupSize(popupLayoutParams.width, -1);
|
||||||
checkPositionBounds();
|
checkPopupPositionBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
if (DEBUG) Log.d(TAG, "onDestroy() called");
|
if (DEBUG) Log.d(TAG, "onDestroy() called");
|
||||||
onClose();
|
closePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -186,7 +199,6 @@ public final class PopupVideoPlayer extends Service {
|
||||||
View rootView = View.inflate(this, R.layout.player_popup, null);
|
View rootView = View.inflate(this, R.layout.player_popup, null);
|
||||||
playerImpl.setup(rootView);
|
playerImpl.setup(rootView);
|
||||||
|
|
||||||
shutdownFlingVelocity = PlayerHelper.getShutdownFlingVelocity(this);
|
|
||||||
tossFlingVelocity = PlayerHelper.getTossFlingVelocity(this);
|
tossFlingVelocity = PlayerHelper.getTossFlingVelocity(this);
|
||||||
|
|
||||||
updateScreenSize();
|
updateScreenSize();
|
||||||
|
@ -200,27 +212,52 @@ public final class PopupVideoPlayer extends Service {
|
||||||
WindowManager.LayoutParams.TYPE_PHONE :
|
WindowManager.LayoutParams.TYPE_PHONE :
|
||||||
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||||
|
|
||||||
windowLayoutParams = new WindowManager.LayoutParams(
|
popupLayoutParams = new WindowManager.LayoutParams(
|
||||||
(int) popupWidth, (int) getMinimumVideoHeight(popupWidth),
|
(int) popupWidth, (int) getMinimumVideoHeight(popupWidth),
|
||||||
layoutParamType,
|
layoutParamType,
|
||||||
IDLE_WINDOW_FLAGS,
|
IDLE_WINDOW_FLAGS,
|
||||||
PixelFormat.TRANSLUCENT);
|
PixelFormat.TRANSLUCENT);
|
||||||
windowLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
|
popupLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
|
||||||
windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
|
popupLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
|
||||||
|
|
||||||
int centerX = (int) (screenWidth / 2f - popupWidth / 2f);
|
int centerX = (int) (screenWidth / 2f - popupWidth / 2f);
|
||||||
int centerY = (int) (screenHeight / 2f - popupHeight / 2f);
|
int centerY = (int) (screenHeight / 2f - popupHeight / 2f);
|
||||||
windowLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX;
|
popupLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX;
|
||||||
windowLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY;
|
popupLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY;
|
||||||
|
|
||||||
checkPositionBounds();
|
checkPopupPositionBounds();
|
||||||
|
|
||||||
MySimpleOnGestureListener listener = new MySimpleOnGestureListener();
|
PopupWindowGestureListener listener = new PopupWindowGestureListener();
|
||||||
gestureDetector = new GestureDetector(this, listener);
|
popupGestureDetector = new GestureDetector(this, listener);
|
||||||
rootView.setOnTouchListener(listener);
|
rootView.setOnTouchListener(listener);
|
||||||
playerImpl.getLoadingPanel().setMinimumWidth(windowLayoutParams.width);
|
|
||||||
playerImpl.getLoadingPanel().setMinimumHeight(windowLayoutParams.height);
|
playerImpl.getLoadingPanel().setMinimumWidth(popupLayoutParams.width);
|
||||||
windowManager.addView(rootView, windowLayoutParams);
|
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,44 +317,105 @@ public final class PopupVideoPlayer extends Service {
|
||||||
// Misc
|
// Misc
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
public void onClose() {
|
public void closePopup() {
|
||||||
if (DEBUG) Log.d(TAG, "onClose() called");
|
if (DEBUG) Log.d(TAG, "closePopup() called, isPopupClosing = " + isPopupClosing);
|
||||||
|
if (isPopupClosing) return;
|
||||||
|
isPopupClosing = true;
|
||||||
|
|
||||||
if (playerImpl != null) {
|
if (playerImpl != null) {
|
||||||
if (playerImpl.getRootView() != null) {
|
if (playerImpl.getRootView() != null) {
|
||||||
windowManager.removeView(playerImpl.getRootView());
|
windowManager.removeView(playerImpl.getRootView());
|
||||||
playerImpl.setRootView(null);
|
|
||||||
}
|
}
|
||||||
|
playerImpl.setRootView(null);
|
||||||
playerImpl.stopActivityBinding();
|
playerImpl.stopActivityBinding();
|
||||||
playerImpl.destroy();
|
playerImpl.destroy();
|
||||||
|
playerImpl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBinder = null;
|
||||||
if (lockManager != null) lockManager.releaseWifiAndCpu();
|
if (lockManager != null) lockManager.releaseWifiAndCpu();
|
||||||
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
||||||
mBinder = null;
|
|
||||||
playerImpl = null;
|
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);
|
stopForeground(true);
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Utils
|
// Utils
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
private void checkPositionBounds() {
|
/**
|
||||||
if (windowLayoutParams.x > screenWidth - windowLayoutParams.width)
|
* @see #checkPopupPositionBounds(float, float)
|
||||||
windowLayoutParams.x = (int) (screenWidth - windowLayoutParams.width);
|
*/
|
||||||
if (windowLayoutParams.x < 0) windowLayoutParams.x = 0;
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
if (windowLayoutParams.y > screenHeight - windowLayoutParams.height)
|
private boolean checkPopupPositionBounds() {
|
||||||
windowLayoutParams.y = (int) (screenHeight - windowLayoutParams.height);
|
return checkPopupPositionBounds(screenWidth, screenHeight);
|
||||||
if (windowLayoutParams.y < 0) windowLayoutParams.y = 0;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if {@link #popupLayoutParams}' position is within a arbitrary boundary that goes from (0,0) to (boundaryWidth,boundaryHeight).
|
||||||
|
* <p>
|
||||||
|
* 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() {
|
private void savePositionAndSize() {
|
||||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PopupVideoPlayer.this);
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PopupVideoPlayer.this);
|
||||||
sharedPreferences.edit().putInt(POPUP_SAVED_X, windowLayoutParams.x).apply();
|
sharedPreferences.edit().putInt(POPUP_SAVED_X, popupLayoutParams.x).apply();
|
||||||
sharedPreferences.edit().putInt(POPUP_SAVED_Y, windowLayoutParams.y).apply();
|
sharedPreferences.edit().putInt(POPUP_SAVED_Y, popupLayoutParams.y).apply();
|
||||||
sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, windowLayoutParams.width).apply();
|
sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, popupLayoutParams.width).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getMinimumVideoHeight(float width) {
|
private float getMinimumVideoHeight(float width) {
|
||||||
|
@ -352,13 +450,13 @@ public final class PopupVideoPlayer extends Service {
|
||||||
if (height == -1) height = (int) getMinimumVideoHeight(width);
|
if (height == -1) height = (int) getMinimumVideoHeight(width);
|
||||||
else height = (int) (height > maximumHeight ? maximumHeight : height < minimumHeight ? minimumHeight : height);
|
else height = (int) (height > maximumHeight ? maximumHeight : height < minimumHeight ? minimumHeight : height);
|
||||||
|
|
||||||
windowLayoutParams.width = width;
|
popupLayoutParams.width = width;
|
||||||
windowLayoutParams.height = height;
|
popupLayoutParams.height = height;
|
||||||
popupWidth = width;
|
popupWidth = width;
|
||||||
popupHeight = height;
|
popupHeight = height;
|
||||||
|
|
||||||
if (DEBUG) Log.d(TAG, "updatePopupSize() updated values: width = [" + width + "], height = [" + 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) {
|
protected void setRepeatModeRemote(final RemoteViews remoteViews, final int repeatMode) {
|
||||||
|
@ -380,10 +478,10 @@ public final class PopupVideoPlayer extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateWindowFlags(final int flags) {
|
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;
|
popupLayoutParams.flags = flags;
|
||||||
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams);
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -393,6 +491,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
private ImageView videoPlayPause;
|
private ImageView videoPlayPause;
|
||||||
|
|
||||||
private View extraOptionsView;
|
private View extraOptionsView;
|
||||||
|
private View closingOverlayView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleIntent(Intent intent) {
|
public void handleIntent(Intent intent) {
|
||||||
|
@ -413,12 +512,18 @@ public final class PopupVideoPlayer extends Service {
|
||||||
fullScreenButton = rootView.findViewById(R.id.fullScreenButton);
|
fullScreenButton = rootView.findViewById(R.id.fullScreenButton);
|
||||||
fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked());
|
fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked());
|
||||||
videoPlayPause = rootView.findViewById(R.id.videoPlayPause);
|
videoPlayPause = rootView.findViewById(R.id.videoPlayPause);
|
||||||
videoPlayPause.setOnClickListener(this::onPlayPauseButtonPressed);
|
|
||||||
|
|
||||||
extraOptionsView = rootView.findViewById(R.id.extraOptionsView);
|
extraOptionsView = rootView.findViewById(R.id.extraOptionsView);
|
||||||
|
closingOverlayView = rootView.findViewById(R.id.closingOverlay);
|
||||||
rootView.addOnLayoutChangeListener(this);
|
rootView.addOnLayoutChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initListeners() {
|
||||||
|
super.initListeners();
|
||||||
|
videoPlayPause.setOnClickListener(v -> onPlayPause());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupSubtitleView(@NonNull SubtitleView view,
|
protected void setupSubtitleView(@NonNull SubtitleView view,
|
||||||
final float captionScale,
|
final float captionScale,
|
||||||
|
@ -429,10 +534,6 @@ public final class PopupVideoPlayer extends Service {
|
||||||
view.setStyle(captionStyle);
|
view.setStyle(captionStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onPlayPauseButtonPressed(View ib) {
|
|
||||||
onPlayPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLayoutChange(final View view, int left, int top, int right, int bottom,
|
public void onLayoutChange(final View view, int left, int top, int right, int bottom,
|
||||||
int oldLeft, int oldTop, int oldRight, int oldBottom) {
|
int oldLeft, int oldTop, int oldRight, int oldBottom) {
|
||||||
|
@ -476,7 +577,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
}
|
}
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
onClose();
|
closePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -634,7 +735,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackShutdown() {
|
public void onPlaybackShutdown() {
|
||||||
super.onPlaybackShutdown();
|
super.onPlaybackShutdown();
|
||||||
onClose();
|
closePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -660,7 +761,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]");
|
if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]");
|
||||||
switch (intent.getAction()) {
|
switch (intent.getAction()) {
|
||||||
case ACTION_CLOSE:
|
case ACTION_CLOSE:
|
||||||
onClose();
|
closePopup();
|
||||||
break;
|
break;
|
||||||
case ACTION_PLAY_PAUSE:
|
case ACTION_PLAY_PAUSE:
|
||||||
onPlayPause();
|
onPlayPause();
|
||||||
|
@ -791,12 +892,15 @@ public final class PopupVideoPlayer extends Service {
|
||||||
public TextView getResizingIndicator() {
|
public TextView getResizingIndicator() {
|
||||||
return resizingIndicator;
|
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 int initialPopupX, initialPopupY;
|
||||||
private boolean isMoving;
|
private boolean isMoving;
|
||||||
|
|
||||||
private boolean isResizing;
|
private boolean isResizing;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -832,10 +936,15 @@ public final class PopupVideoPlayer extends Service {
|
||||||
@Override
|
@Override
|
||||||
public boolean onDown(MotionEvent e) {
|
public boolean onDown(MotionEvent e) {
|
||||||
if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]");
|
if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]");
|
||||||
initialPopupX = windowLayoutParams.x;
|
|
||||||
initialPopupY = windowLayoutParams.y;
|
// Fix popup position when the user touch it, it may have the wrong one
|
||||||
popupWidth = windowLayoutParams.width;
|
// because the soft input is visible (the draggable area is currently resized).
|
||||||
popupHeight = windowLayoutParams.height;
|
checkPopupPositionBounds(closeOverlayView.getWidth(), closeOverlayView.getHeight());
|
||||||
|
|
||||||
|
initialPopupX = popupLayoutParams.x;
|
||||||
|
initialPopupY = popupLayoutParams.y;
|
||||||
|
popupWidth = popupLayoutParams.width;
|
||||||
|
popupHeight = popupLayoutParams.height;
|
||||||
return super.onDown(e);
|
return super.onDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,20 +952,22 @@ public final class PopupVideoPlayer extends Service {
|
||||||
public void onLongPress(MotionEvent e) {
|
public void onLongPress(MotionEvent e) {
|
||||||
if (DEBUG) Log.d(TAG, "onLongPress() called with: e = [" + e + "]");
|
if (DEBUG) Log.d(TAG, "onLongPress() called with: e = [" + e + "]");
|
||||||
updateScreenSize();
|
updateScreenSize();
|
||||||
checkPositionBounds();
|
checkPopupPositionBounds();
|
||||||
updatePopupSize((int) screenWidth, -1);
|
updatePopupSize((int) screenWidth, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
public boolean onScroll(MotionEvent initialEvent, MotionEvent movingEvent, float distanceX, float distanceY) {
|
||||||
if (isResizing || playerImpl == null) return super.onScroll(e1, e2, distanceX, distanceY);
|
if (isResizing || playerImpl == null) return super.onScroll(initialEvent, movingEvent, distanceX, distanceY);
|
||||||
|
|
||||||
|
if (!isMoving) {
|
||||||
|
animateView(closeOverlayButton, true, 200);
|
||||||
|
}
|
||||||
|
|
||||||
if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING
|
|
||||||
&& (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0);
|
|
||||||
isMoving = true;
|
isMoving = true;
|
||||||
|
|
||||||
float diffX = (int) (e2.getRawX() - e1.getRawX()), posX = (int) (initialPopupX + diffX);
|
float diffX = (int) (movingEvent.getRawX() - initialEvent.getRawX()), posX = (int) (initialPopupX + diffX);
|
||||||
float diffY = (int) (e2.getRawY() - e1.getRawY()), posY = (int) (initialPopupY + diffY);
|
float diffY = (int) (movingEvent.getRawY() - initialEvent.getRawY()), posY = (int) (initialPopupY + diffY);
|
||||||
|
|
||||||
if (posX > (screenWidth - popupWidth)) posX = (int) (screenWidth - popupWidth);
|
if (posX > (screenWidth - popupWidth)) posX = (int) (screenWidth - popupWidth);
|
||||||
else if (posX < 0) posX = 0;
|
else if (posX < 0) posX = 0;
|
||||||
|
@ -864,26 +975,49 @@ public final class PopupVideoPlayer extends Service {
|
||||||
if (posY > (screenHeight - popupHeight)) posY = (int) (screenHeight - popupHeight);
|
if (posY > (screenHeight - popupHeight)) posY = (int) (screenHeight - popupHeight);
|
||||||
else if (posY < 0) posY = 0;
|
else if (posY < 0) posY = 0;
|
||||||
|
|
||||||
windowLayoutParams.x = (int) posX;
|
popupLayoutParams.x = (int) posX;
|
||||||
windowLayoutParams.y = (int) posY;
|
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
|
//noinspection PointlessBooleanExpression
|
||||||
if (DEBUG && false) Log.d(TAG, "PopupVideoPlayer.onScroll = " +
|
if (DEBUG && false) {
|
||||||
", e1.getRaw = [" + e1.getRawX() + ", " + e1.getRawY() + "]" +
|
Log.d(TAG, "PopupVideoPlayer.onScroll = " +
|
||||||
", e2.getRaw = [" + e2.getRawX() + ", " + e2.getRawY() + "]" +
|
", e1.getRaw = [" + initialEvent.getRawX() + ", " + initialEvent.getRawY() + "]" + ", e1.getX,Y = [" + initialEvent.getX() + ", " + initialEvent.getY() + "]" +
|
||||||
", distanceXy = [" + distanceX + ", " + distanceY + "]" +
|
", e2.getRaw = [" + movingEvent.getRawX() + ", " + movingEvent.getRawY() + "]" + ", e2.getX,Y = [" + movingEvent.getX() + ", " + movingEvent.getY() + "]" +
|
||||||
", posXy = [" + posX + ", " + posY + "]" +
|
", distanceX,Y = [" + distanceX + ", " + distanceY + "]" +
|
||||||
", popupWh = [" + popupWidth + " x " + popupHeight + "]");
|
", posX,Y = [" + posX + ", " + posY + "]" +
|
||||||
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
", popupW,H = [" + popupWidth + " x " + popupHeight + "]");
|
||||||
|
}
|
||||||
|
windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScrollEnd() {
|
private void onScrollEnd(MotionEvent event) {
|
||||||
if (DEBUG) Log.d(TAG, "onScrollEnd() called");
|
if (DEBUG) Log.d(TAG, "onScrollEnd() called");
|
||||||
if (playerImpl == null) return;
|
if (playerImpl == null) return;
|
||||||
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
|
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
|
||||||
playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
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
|
@Override
|
||||||
|
@ -893,14 +1027,11 @@ public final class PopupVideoPlayer extends Service {
|
||||||
|
|
||||||
final float absVelocityX = Math.abs(velocityX);
|
final float absVelocityX = Math.abs(velocityX);
|
||||||
final float absVelocityY = Math.abs(velocityY);
|
final float absVelocityY = Math.abs(velocityY);
|
||||||
if (absVelocityX > shutdownFlingVelocity) {
|
if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) {
|
||||||
onClose();
|
if (absVelocityX > tossFlingVelocity) popupLayoutParams.x = (int) velocityX;
|
||||||
return true;
|
if (absVelocityY > tossFlingVelocity) popupLayoutParams.y = (int) velocityY;
|
||||||
} else if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) {
|
checkPopupPositionBounds();
|
||||||
if (absVelocityX > tossFlingVelocity) windowLayoutParams.x = (int) velocityX;
|
windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams);
|
||||||
if (absVelocityY > tossFlingVelocity) windowLayoutParams.y = (int) velocityY;
|
|
||||||
checkPositionBounds();
|
|
||||||
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -908,7 +1039,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
gestureDetector.onTouchEvent(event);
|
popupGestureDetector.onTouchEvent(event);
|
||||||
if (playerImpl == null) return false;
|
if (playerImpl == null) return false;
|
||||||
if (event.getPointerCount() == 2 && !isResizing) {
|
if (event.getPointerCount() == 2 && !isResizing) {
|
||||||
if (DEBUG) Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing.");
|
if (DEBUG) Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing.");
|
||||||
|
@ -931,7 +1062,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]");
|
Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]");
|
||||||
if (isMoving) {
|
if (isMoving) {
|
||||||
isMoving = false;
|
isMoving = false;
|
||||||
onScrollEnd();
|
onScrollEnd(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isResizing) {
|
if (isResizing) {
|
||||||
|
@ -939,8 +1070,11 @@ public final class PopupVideoPlayer extends Service {
|
||||||
animateView(playerImpl.getResizingIndicator(), false, 100, 0);
|
animateView(playerImpl.getResizingIndicator(), false, 100, 0);
|
||||||
playerImpl.changeState(playerImpl.getCurrentState());
|
playerImpl.changeState(playerImpl.getCurrentState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isPopupClosing) {
|
||||||
savePositionAndSize();
|
savePositionAndSize();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v.performClick();
|
v.performClick();
|
||||||
return true;
|
return true;
|
||||||
|
@ -955,13 +1089,13 @@ public final class PopupVideoPlayer extends Service {
|
||||||
final float diff = Math.abs(firstPointerX - secondPointerX);
|
final float diff = Math.abs(firstPointerX - secondPointerX);
|
||||||
if (firstPointerX > secondPointerX) {
|
if (firstPointerX > secondPointerX) {
|
||||||
// second pointer is the anchor (the leftmost pointer)
|
// second pointer is the anchor (the leftmost pointer)
|
||||||
windowLayoutParams.x = (int) (event.getRawX() - diff);
|
popupLayoutParams.x = (int) (event.getRawX() - diff);
|
||||||
} else {
|
} else {
|
||||||
// first pointer is the anchor
|
// first pointer is the anchor
|
||||||
windowLayoutParams.x = (int) event.getRawX();
|
popupLayoutParams.x = (int) event.getRawX();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPositionBounds();
|
checkPopupPositionBounds();
|
||||||
updateScreenSize();
|
updateScreenSize();
|
||||||
|
|
||||||
final int width = (int) Math.min(screenWidth, diff);
|
final int width = (int) Math.min(screenWidth, diff);
|
||||||
|
@ -969,5 +1103,29 @@ public final class PopupVideoPlayer extends Service {
|
||||||
|
|
||||||
return true;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -251,10 +251,6 @@ public class PlayerHelper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getShutdownFlingVelocity(@NonNull final Context context) {
|
|
||||||
return 6000;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getTossFlingVelocity(@NonNull final Context context) {
|
public static int getTossFlingVelocity(@NonNull final Context context) {
|
||||||
return 2500;
|
return 2500;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
tools:layout_height="84dp"
|
tools:layout_height="84dp"
|
||||||
tools:layout_width="@dimen/popup_minimum_width">
|
tools:layout_width="@dimen/popup_minimum_width">
|
||||||
|
|
||||||
|
|
||||||
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
|
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
|
||||||
android:id="@+id/aspectRatioLayout"
|
android:id="@+id/aspectRatioLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -290,4 +289,11 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:ignore="RtlHardcoded"
|
tools:ignore="RtlHardcoded"
|
||||||
tools:visibility="gone"/>
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/closingOverlay"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#AAFF0000"
|
||||||
|
android:visibility="gone"/>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
android:id="@+id/closeButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
android:src="@drawable/ic_close_white_24dp"
|
||||||
|
app:backgroundTint="@color/light_youtube_primary_color"
|
||||||
|
app:borderWidth="0dp"
|
||||||
|
app:fabSize="normal"/>
|
||||||
|
</FrameLayout>
|
Loading…
Reference in New Issue