159 lines
6.5 KiB
Diff
159 lines
6.5 KiB
Diff
From: uazo <uazo@users.noreply.github.com>
|
|
Date: Mon, 18 Aug 2025 13:46:14 +0000
|
|
Subject: Enable snackbar swipe
|
|
|
|
Allows swipe of snackbar notifications
|
|
|
|
License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
|
|
---
|
|
.../ui/messages/snackbar/SnackbarView.java | 91 ++++++++++++++++---
|
|
1 file changed, 77 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
|
|
--- a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
|
|
+++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
|
|
@@ -9,14 +9,17 @@ import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.AnimatorSet;
|
|
import android.animation.ObjectAnimator;
|
|
import android.app.Activity;
|
|
+import android.content.Context;
|
|
import android.graphics.Rect;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.graphics.drawable.GradientDrawable;
|
|
import android.util.Pair;
|
|
+import android.view.MotionEvent;
|
|
import android.view.Gravity;
|
|
import android.view.LayoutInflater;
|
|
import android.view.SurfaceView;
|
|
import android.view.View;
|
|
+import android.view.View.OnClickListener;
|
|
import android.view.View.OnLayoutChangeListener;
|
|
import android.view.ViewGroup;
|
|
import android.widget.FrameLayout;
|
|
@@ -36,6 +39,8 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarSwipeHandler.Del
|
|
import org.chromium.chrome.ui.messages.R;
|
|
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
|
|
import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener;
|
|
+import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.ScrollDirection;
|
|
+import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler;
|
|
import org.chromium.components.browser_ui.widget.text.TemplatePreservingTextView;
|
|
import org.chromium.ui.base.WindowAndroid;
|
|
import org.chromium.ui.insets.InsetObserver;
|
|
@@ -48,7 +53,7 @@ import org.chromium.ui.interpolators.Interpolators;
|
|
// TODO (jianli): Change this class and its methods back to package protected after the offline
|
|
// indicator experiment is done.
|
|
@NullMarked
|
|
-public class SnackbarView implements InsetObserver.WindowInsetObserver {
|
|
+public class SnackbarView implements InsetObserver.WindowInsetObserver, View.OnTouchListener, SwipeHandler {
|
|
private static final int MAX_LINES = 5;
|
|
private static final int DEFAULT_LINES = 2;
|
|
|
|
@@ -96,6 +101,16 @@ public class SnackbarView implements InsetObserver.WindowInsetObserver {
|
|
}
|
|
};
|
|
|
|
+ private final SwipeGestureListenerImpl mSwipeGestureListener;
|
|
+ private final OnClickListener mDismissListener;
|
|
+ private final float mHorizontalTranslationPx;
|
|
+
|
|
+ private class SwipeGestureListenerImpl extends SwipeGestureListener {
|
|
+ public SwipeGestureListenerImpl(Context context, SwipeHandler handler) {
|
|
+ super(context, handler);
|
|
+ }
|
|
+ }
|
|
+
|
|
/**
|
|
* Creates an instance of the {@link SnackbarView}.
|
|
*
|
|
@@ -151,21 +166,15 @@ public class SnackbarView implements InsetObserver.WindowInsetObserver {
|
|
adjustViewPosition();
|
|
}
|
|
});
|
|
- SwipeGestureListener swipeGestureListener =
|
|
- new SwipeGestureListener(activity, mSnackbarSwipeHandler);
|
|
-
|
|
+ mSwipeGestureListener =
|
|
+ new SwipeGestureListenerImpl(mContainerView.getContext(), this);
|
|
// Make sure clicks are not consumed by content beneath the container view.
|
|
mContainerView.setClickable(true);
|
|
- mContainerView.setOnClickListener((event) -> manager.resetSnackbarTimeout());
|
|
- mContainerView.setOnTouchListener(
|
|
- (view, event) -> {
|
|
- if (swipeGestureListener.onTouchEvent(event)) return true;
|
|
- // Disable touch inputs during animation.
|
|
- if (mIsAnimating) return true;
|
|
- mContainerView.performClick();
|
|
- return true;
|
|
- });
|
|
-
|
|
+ if (!snackbar.isTypePersistent()) {
|
|
+ mContainerView.setOnTouchListener(this);
|
|
+ }
|
|
+ mDismissListener = dismissListener;
|
|
+ mHorizontalTranslationPx = mContainerView.getResources().getDisplayMetrics().widthPixels / 3;
|
|
mSnackbarView = mContainerView.findViewById(R.id.snackbar);
|
|
mAnimationDuration =
|
|
mContainerView.getResources().getInteger(android.R.integer.config_mediumAnimTime);
|
|
@@ -311,6 +320,60 @@ public class SnackbarView implements InsetObserver.WindowInsetObserver {
|
|
return mContainerView.isShown();
|
|
}
|
|
|
|
+ @Override
|
|
+ public boolean onTouch(View v, MotionEvent event) {
|
|
+ return mSwipeGestureListener.onTouchEvent(event);
|
|
+ }
|
|
+
|
|
+ private boolean mSwipeStarted;
|
|
+ private float mCurrentSwipePosition;
|
|
+
|
|
+ @Override
|
|
+ public void onSwipeStarted(@ScrollDirection int direction, MotionEvent ev) {
|
|
+ mContainerView.setTranslationX(0);
|
|
+ mSwipeStarted = true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onSwipeUpdated(MotionEvent current, float tx, float ty, float dx, float dy) {
|
|
+ if (!mSwipeStarted) return;
|
|
+ mCurrentSwipePosition = Math.abs(tx);
|
|
+ mContainerView.setTranslationX(tx);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onSwipeFinished() {
|
|
+ if (!mSwipeStarted) return;
|
|
+ mSwipeStarted = false;
|
|
+ if (mCurrentSwipePosition >= mHorizontalTranslationPx) {
|
|
+ mDismissListener.onClick(mDismissButtonView);
|
|
+ return;
|
|
+ }
|
|
+ mContainerView.setTranslationX(0);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onFling(
|
|
+ @ScrollDirection int direction,
|
|
+ MotionEvent current,
|
|
+ float tx,
|
|
+ float ty,
|
|
+ float vx,
|
|
+ float vy) {
|
|
+ if (!mSwipeStarted) return;
|
|
+ mSwipeStarted = false;
|
|
+ if (mCurrentSwipePosition >= mHorizontalTranslationPx) {
|
|
+ mDismissListener.onClick(mDismissButtonView);
|
|
+ return;
|
|
+ }
|
|
+ mContainerView.setTranslationX(0);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isSwipeEnabled(@ScrollDirection int direction) {
|
|
+ return direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT;
|
|
+ }
|
|
+
|
|
void bringToFront() {
|
|
mContainerView.bringToFront();
|
|
}
|
|
--
|