Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(993)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java

Issue 1759483002: [Snackbar] Replace popup window with views (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java
index c858cab44dfa7b5ff13777584f56fd54d584ee75..0475fd92a5bf7acc256cb9355784e408b3a9bdf9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarManager.java
@@ -4,20 +4,13 @@
package org.chromium.chrome.browser.snackbar;
-import android.graphics.Rect;
import android.os.Handler;
-import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-import android.view.Window;
+import android.view.ViewGroup;
-import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting;
-import org.chromium.chrome.R;
import org.chromium.chrome.browser.device.DeviceClassManager;
-import org.chromium.ui.UiUtils;
-import org.chromium.ui.base.DeviceFormFactor;
/**
* Manager for the snackbar showing at the bottom of activity. There should be only one
@@ -28,7 +21,7 @@ import org.chromium.ui.base.DeviceFormFactor;
* during {@link #DEFAULT_SNACKBAR_DURATION_MS} milliseconds, it will call
* {@link SnackbarController#onDismissNoAction(Object)}.
*/
-public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener {
+public class SnackbarManager implements OnClickListener {
/**
* Interface that shows the ability to provide a snackbar manager. Activities implementing this
@@ -77,32 +70,27 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
private static int sSnackbarDurationMs = DEFAULT_SNACKBAR_DURATION_MS;
private static int sAccessibilitySnackbarDurationMs = ACCESSIBILITY_MODE_SNACKBAR_DURATION_MS;
- private final boolean mIsTablet;
-
- private View mDecor;
+ private ViewGroup mParentView;
+ private SnackbarView mView;
private final Handler mUIThreadHandler;
private SnackbarCollection mSnackbars = new SnackbarCollection();
- private SnackbarPopupWindow mPopup;
private boolean mActivityInForeground;
+ private boolean mIsDisabledForTesting;
private final Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
mSnackbars.removeCurrentDueToTimeout();
- updatePopup();
+ updateView();
}
};
- // Variables used and reused in popup position calculations.
- private int[] mTempDecorPosition = new int[2];
- private Rect mTempVisibleDisplayFrame = new Rect();
-
/**
* Constructs a SnackbarManager to show snackbars in the given window.
+ * @param rootView The main view (e.g. android.R.id.content) of the embedding activity.
*/
- public SnackbarManager(Window window) {
- mDecor = window.getDecorView();
+ public SnackbarManager(ViewGroup rootView) {
+ mParentView = rootView;
mUIThreadHandler = new Handler();
- mIsTablet = DeviceFormFactor.isTablet(mDecor.getContext());
}
/**
@@ -117,7 +105,7 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
*/
public void onStop() {
mSnackbars.clear();
- updatePopup();
+ updateView();
mActivityInForeground = false;
}
@@ -126,10 +114,10 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
* visible.
*/
public void showSnackbar(Snackbar snackbar) {
- if (!mActivityInForeground) return;
+ if (!mActivityInForeground || mIsDisabledForTesting) return;
mSnackbars.add(snackbar);
- updatePopup();
- mPopup.announceforAccessibility();
+ updateView();
+ mView.announceforAccessibility();
}
/**
@@ -139,7 +127,7 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
*/
public void dismissSnackbars(SnackbarController controller) {
if (mSnackbars.removeMatchingSnackbars(controller)) {
- updatePopup();
+ updateView();
}
}
@@ -151,7 +139,7 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
*/
public void dismissSnackbars(SnackbarController controller, Object actionData) {
if (mSnackbars.removeMatchingSnackbars(controller, actionData)) {
- updatePopup();
+ updateView();
}
}
@@ -162,7 +150,7 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
*/
public void dismissSnackbars(SnackbarController controller, ActionDataMatcher selector) {
if (mSnackbars.removeMatchingSnackbars(controller, selector)) {
- updatePopup();
+ updateView();
}
}
@@ -172,87 +160,43 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
@Override
public void onClick(View v) {
mSnackbars.removeCurrentDueToAction();
- updatePopup();
+ updateView();
}
/**
* @return Whether there is a snackbar on screen.
*/
public boolean isShowing() {
- return mPopup != null && mPopup.isShowing();
+ return mView != null && mView.isShowing();
}
/**
- * Resize and re-position popup window when the device orientation changes or the software
- * keyboard appears. Be careful not to let the snackbar overlap the Android navigation bar:
- * http://b/17789629.
+ * Updates the {@link SnackbarView} to reflect the value of mSnackbars.currentSnackbar(), which
+ * may be null. This might show, change, or hide the view.
*/
- @Override
- public void onGlobalLayout() {
- if (mPopup == null) return;
-
- mDecor.getLocationInWindow(mTempDecorPosition);
- mDecor.getWindowVisibleDisplayFrame(mTempVisibleDisplayFrame);
- int decorBottom = mTempDecorPosition[1] + mDecor.getHeight();
- int visibleBottom = Math.min(mTempVisibleDisplayFrame.bottom, decorBottom);
-
- if (mIsTablet) {
- int margin = mDecor.getResources().getDimensionPixelOffset(
- R.dimen.snackbar_tablet_margin);
- int width = mDecor.getResources().getDimensionPixelSize(R.dimen.snackbar_tablet_width);
- boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(mDecor);
- int startPosition = isRtl ? mDecor.getRight() - width - margin
- : mDecor.getLeft() + margin;
- mPopup.update(startPosition, decorBottom - visibleBottom + margin, width, -1);
- } else {
- mPopup.update(mDecor.getLeft(), decorBottom - visibleBottom, mDecor.getWidth(), -1);
- }
- }
-
- /**
- * Updates the snackbar popup window to reflect the value of mSnackbars.currentSnackbar(), which
- * may be null. This might show, change, or hide the popup.
- */
- private void updatePopup() {
+ private void updateView() {
if (!mActivityInForeground) return;
Snackbar currentSnackbar = mSnackbars.getCurrent();
if (currentSnackbar == null) {
mUIThreadHandler.removeCallbacks(mHideRunnable);
- if (mPopup != null) {
- mPopup.dismiss();
- mPopup = null;
+ if (mView != null) {
+ mView.dismiss();
+ mView = null;
}
- mDecor.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
- boolean popupChanged = true;
- if (mPopup == null) {
- mPopup = new SnackbarPopupWindow(mDecor, this, currentSnackbar);
- // When the keyboard is showing, translating the snackbar upwards looks bad because
- // it overlaps the keyboard. In this case, use an alternative animation without
- // translation.
- boolean isKeyboardShowing = UiUtils.isKeyboardShowing(mDecor.getContext(), mDecor);
- mPopup.setAnimationStyle(isKeyboardShowing ? R.style.SnackbarAnimationWithKeyboard
- : R.style.SnackbarAnimation);
-
- mDecor.getLocationInWindow(mTempDecorPosition);
- mDecor.getWindowVisibleDisplayFrame(mTempVisibleDisplayFrame);
- int decorBottom = mTempDecorPosition[1] + mDecor.getHeight();
- int visibleBottom = Math.min(mTempVisibleDisplayFrame.bottom, decorBottom);
- int margin = mIsTablet ? mDecor.getResources().getDimensionPixelSize(
- R.dimen.snackbar_tablet_margin) : 0;
-
- mPopup.showAtLocation(mDecor, Gravity.START | Gravity.BOTTOM, margin,
- decorBottom - visibleBottom + margin);
- mDecor.getViewTreeObserver().addOnGlobalLayoutListener(this);
+ boolean viewChanged = true;
+ if (mView == null) {
+ mView = new SnackbarView(mParentView, this, currentSnackbar);
+ mView.show();
} else {
- popupChanged = mPopup.update(currentSnackbar);
+ viewChanged = mView.update(currentSnackbar);
}
- if (popupChanged) {
+ if (viewChanged) {
int durationMs = getDuration(currentSnackbar);
mUIThreadHandler.removeCallbacks(mHideRunnable);
mUIThreadHandler.postDelayed(mHideRunnable, durationMs);
- mPopup.announceforAccessibility();
+ mView.announceforAccessibility();
}
}
@@ -261,13 +205,21 @@ public class SnackbarManager implements OnClickListener, OnGlobalLayoutListener
private int getDuration(Snackbar snackbar) {
int durationMs = snackbar.getDuration();
if (durationMs == 0) {
- durationMs = DeviceClassManager.isAccessibilityModeEnabled(mDecor.getContext())
+ durationMs = DeviceClassManager.isAccessibilityModeEnabled(mParentView.getContext())
? sAccessibilitySnackbarDurationMs : sSnackbarDurationMs;
}
return durationMs;
}
/**
+ * Disables the snackbar manager. This is only intented for testing purposes.
+ */
+ @VisibleForTesting
+ public void disableForTesting() {
+ mIsDisabledForTesting = true;
+ }
+
+ /**
* Overrides the default snackbar duration with a custom value for testing.
* @param durationMs The duration to use in ms.
*/

Powered by Google App Engine
This is Rietveld 408576698