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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java

Issue 893483002: Make infobars hide on scroll (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Observer removal Created 5 years, 11 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/banners/SwipableOverlayView.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java b/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java
index aa655442131e35e9146ed69de7663a09da07c869..17d10ffb632ac5357cd35e5a7617d2f797b5b640 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/banners/SwipableOverlayView.java
@@ -20,7 +20,11 @@ import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import android.widget.ScrollView;
+import org.chromium.chrome.browser.EmptyTabObserver;
+import org.chromium.chrome.browser.Tab;
+import org.chromium.chrome.browser.TabObserver;
import org.chromium.content.browser.ContentViewCore;
import org.chromium.content_public.browser.GestureStateListener;
import org.chromium.ui.UiUtils;
@@ -67,12 +71,13 @@ import org.chromium.ui.UiUtils;
* fling is completed, the more forgiving FLING_THRESHOLD is used to determine how far a user must
* swipe to dismiss the View rather than try to use the fling velocity.
*/
-public abstract class SwipableOverlayView extends FrameLayout {
+public abstract class SwipableOverlayView extends ScrollView {
private static final float ALPHA_THRESHOLD = 0.25f;
private static final float DISMISS_SWIPE_THRESHOLD = 0.75f;
private static final float FULL_THRESHOLD = 0.5f;
private static final float VERTICAL_FLING_SHOW_THRESHOLD = 0.2f;
private static final float VERTICAL_FLING_HIDE_THRESHOLD = 0.9f;
+ private static final long REATTACH_FADE_IN_MS = 250;
protected static final float ZERO_THRESHOLD = 0.001f;
private static final int GESTURE_NONE = 0;
@@ -87,18 +92,34 @@ public abstract class SwipableOverlayView extends FrameLayout {
private static final long MS_DISMISS_FLING_THRESHOLD = MS_ANIMATION_DURATION * 2;
private static final long MS_SLOW_DISMISS = MS_ANIMATION_DURATION * 3;
+ /** Resets the state of the SwipableOverlayView, as needed. */
+ protected class SwipableOverlayViewTabObserver extends EmptyTabObserver {
+ @Override
+ public void onDidNavigateMainFrame(Tab tab, String url, String baseUrl,
+ boolean isNavigationToDifferentPage, boolean isFragmentNavigation,
+ int statusCode) {
+ setDoStayInvisible(false);
+ }
+ }
+
// Detects when the user is dragging the View.
private final GestureDetector mGestureDetector;
// Detects when the user is dragging the ContentViewCore.
private final GestureStateListener mGestureStateListener;
+ // Listens for changes in the layout.
+ private final View.OnLayoutChangeListener mLayoutChangeListener;
+
// Monitors for animation completions and resets the state.
private final AnimatorListenerAdapter mAnimatorListenerAdapter;
// Interpolator used for the animation.
private final Interpolator mInterpolator;
+ // Observes the Tab.
+ private final TabObserver mTabObserver;
+
// Tracks whether the user is scrolling or flinging.
private int mGestureState;
@@ -135,6 +156,12 @@ public abstract class SwipableOverlayView extends FrameLayout {
// The ContentViewCore to which the overlay is added.
private ContentViewCore mContentViewCore;
+ // Keeps the View from becoming visible when it normally would.
+ private boolean mDoStayInvisible;
+
+ // Whether the View should be allowed to be swiped away.
+ private boolean mIsSwipable = true;
+
/**
* Creates a SwipableOverlayView.
* @param context Context for acquiring resources.
@@ -146,22 +173,53 @@ public abstract class SwipableOverlayView extends FrameLayout {
mGestureDetector = new GestureDetector(context, gestureListener);
mGestureStateListener = createGestureStateListener();
mGestureState = GESTURE_NONE;
+ mLayoutChangeListener = createLayoutChangeListener();
mAnimatorListenerAdapter = createAnimatorListenerAdapter();
mInterpolator = new DecelerateInterpolator(1.0f);
+ mTabObserver = createTabObserver();
+ }
+
+ /**
+ * Indicates whether the View should be allowed to be swiped away.
+ * @param swipable Whether the View is reacts to horizontal gestures.
+ */
+ protected void setIsSwipable(boolean swipable) {
+ mIsSwipable = swipable;
}
/**
- * Adds this View to the given ContentViewCore's view.
- * @param layout Layout to add this View to.
+ * Watches the given ContentViewCore for scrolling changes.
*/
- protected void addToView(ContentViewCore contentViewCore) {
- assert mContentViewCore == null;
+ public void setContentViewCore(ContentViewCore contentViewCore) {
+ if (mContentViewCore != null) {
+ mContentViewCore.removeGestureStateListener(mGestureStateListener);
+ }
+
mContentViewCore = contentViewCore;
- contentViewCore.getContainerView().addView(this, 0, createLayoutParams());
- contentViewCore.addGestureStateListener(mGestureStateListener);
+ if (mContentViewCore != null) {
+ mContentViewCore.addGestureStateListener(mGestureStateListener);
+ }
+ }
+
+ public void addToParentView(ViewGroup parentView) {
+ if (parentView != null && parentView.indexOfChild(this) == -1) {
+ parentView.addView(this, createLayoutParams());
+
+ // Listen for the layout to know when to animate the View coming onto the screen.
+ addOnLayoutChangeListener(mLayoutChangeListener);
+ }
+ }
+
+ /**
+ * Removes the SwipableOverlayView from its parent and stops monitoring the ContentViewCore.
+ * @return Whether the View was removed from its parent.
+ */
+ public boolean removeFromParentView() {
+ if (getParent() == null) return false;
- // Listen for the layout to know when to animate the View coming onto the screen.
- addOnLayoutChangeListener(createLayoutChangeListener());
+ ((ViewGroup) getParent()).removeView(this);
+ removeOnLayoutChangeListener(mLayoutChangeListener);
+ return true;
}
/**
@@ -169,21 +227,43 @@ public abstract class SwipableOverlayView extends FrameLayout {
* for other types of behavior.
* @return LayoutParams for use when adding the View to its parent.
*/
- protected ViewGroup.MarginLayoutParams createLayoutParams() {
+ public ViewGroup.MarginLayoutParams createLayoutParams() {
return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
}
/**
- * Removes the View from its parent.
+ * Call with {@code true} when a higher priority bottom element is visible to keep the View
+ * from ever becoming visible. Call with {@code false} to restore normal visibility behavior.
+ * @param doStayInvisible Whether the View should stay invisible even when they would
+ * normally become visible.
*/
- boolean removeFromParent() {
- if (mContentViewCore != null) {
- mContentViewCore.getContainerView().removeView(this);
- mContentViewCore = null;
- return true;
+ public void setDoStayInvisible(boolean doStayInvisible) {
+ mDoStayInvisible = doStayInvisible;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!mDoStayInvisible) {
+ ObjectAnimator.ofFloat(this, "alpha", 0.f, 1.f).setDuration(REATTACH_FADE_IN_MS)
+ .start();
+ setVisibility(VISIBLE);
}
- return false;
+ }
+
+ /**
+ * @return TabObserver that can be used to monitor a Tab.
+ */
+ protected TabObserver createTabObserver() {
+ return new SwipableOverlayViewTabObserver();
+ }
+
+ /**
+ * @return TabObserver that is used to monitor a Tab.
+ */
+ public TabObserver getTabObserver() {
+ return mTabObserver;
}
/**
@@ -192,8 +272,16 @@ public abstract class SwipableOverlayView extends FrameLayout {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Hide the View when the keyboard is showing.
- boolean keyboardIsShowing = UiUtils.isKeyboardShowing(getContext(), this);
- setVisibility(keyboardIsShowing ? INVISIBLE : VISIBLE);
+ boolean isShowing = (getVisibility() == View.VISIBLE);
+ if (UiUtils.isKeyboardShowing(getContext(), this)) {
+ if (isShowing) {
+ setVisibility(View.INVISIBLE);
+ }
+ } else {
+ if (!isShowing && !mDoStayInvisible) {
+ setVisibility(View.VISIBLE);
+ }
+ }
// Update the viewport height when the parent View's height changes (e.g. after rotation).
int currentParentHeight = getParent() == null ? 0 : ((View) getParent()).getHeight();
@@ -218,6 +306,8 @@ public abstract class SwipableOverlayView extends FrameLayout {
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (!mIsSwipable) return false;
+
if (mGestureDetector.onTouchEvent(event)) return true;
if (mCurrentAnimation != null) return true;
@@ -391,7 +481,7 @@ public abstract class SwipableOverlayView extends FrameLayout {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
- removeOnLayoutChangeListener(this);
+ removeOnLayoutChangeListener(mLayoutChangeListener);
// Animate the View coming in from the bottom of the screen.
setTranslationY(mTotalHeight);
@@ -560,7 +650,7 @@ public abstract class SwipableOverlayView extends FrameLayout {
return new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (mIsDismissed) removeFromParent();
+ if (mIsDismissed) removeFromParentView();
mGestureState = GESTURE_NONE;
mCurrentAnimation = null;

Powered by Google App Engine
This is Rietveld 408576698