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

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

Issue 1983353002: [Android] Coordinate Infobars and Snackbars (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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/SnackbarView.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java
index 3671d5cb88a5544dca859c46895f8313258f6ddc..cf20bdbb2c914182736e540893829974205a2757 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/snackbar/SnackbarView.java
@@ -4,24 +4,32 @@
package org.chromium.chrome.browser.snackbar;
-import android.content.Context;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.CoordinatorLayout.Behavior;
+import android.support.design.widget.CoordinatorLayout.LayoutParams;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.ui.base.DeviceFormFactor;
/**
@@ -29,13 +37,14 @@ import org.chromium.ui.base.DeviceFormFactor;
* has a fixed width and is anchored at the start-bottom corner of the current window.
*/
class SnackbarView {
+ private final Activity mActivity;
private final ViewGroup mView;
- private final ViewGroup mParent;
private final TemplatePreservingTextView mMessageView;
private final TextView mActionButtonView;
private final ImageView mProfileImageView;
private final int mAnimationDuration;
private final boolean mIsTablet;
+ private ViewGroup mParent;
private Snackbar mSnackbar;
// Variables used to calculate the virtual keyboard's height.
@@ -55,17 +64,39 @@ class SnackbarView {
};
/**
+ * Behavior that intercepts touch event from the CompositorViewHoder.
+ */
+ private Behavior<View> mBehavior = new Behavior<View>() {
gone 2016/05/17 23:48:24 final?
Ian Wen 2016/05/18 00:23:46 Done.
+ @Override
+ public boolean onInterceptTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) {
+ return ev.getX() - child.getX() < child.getWidth()
+ && ev.getY() - child.getY() < child.getHeight();
+ }
+
+ @Override
+ public boolean onTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) {
+ ev.offsetLocation(-child.getX(), -child.getY());
+ boolean consumed = child.dispatchTouchEvent(ev);
+ ev.offsetLocation(child.getX(), child.getY());
+ return consumed;
+ }
+ };
+
+ /**
* Creates an instance of the {@link SnackbarView}.
gone 2016/05/17 23:48:24 Need the @param activity
Ian Wen 2016/05/18 00:23:46 Done.
- * @param parent The main view of the embedding Activity.
* @param listener An {@link OnClickListener} that will be called when the action button is
* clicked.
* @param snackbar The snackbar to be displayed.
*/
- SnackbarView(ViewGroup parent, OnClickListener listener, Snackbar snackbar) {
- Context context = parent.getContext();
- mIsTablet = DeviceFormFactor.isTablet(context);
- mParent = parent;
- mView = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.snackbar, mParent, false);
+ SnackbarView(Activity activity, OnClickListener listener, Snackbar snackbar) {
+ mActivity = activity;
+ mIsTablet = DeviceFormFactor.isTablet(activity);
+ mParent = (ViewGroup) activity.findViewById(R.id.compositor_view_holder);
gone 2016/05/17 23:48:24 This logic is kind of gross because it's directly
Ian Wen 2016/05/18 00:23:46 Good suggestion. Done.
+ if (mParent == null) {
+ mParent = (ViewGroup) activity.findViewById(android.R.id.content);
+ }
+ mView = (ViewGroup) LayoutInflater.from(activity).inflate(R.layout.snackbar, mParent,
gone 2016/05/17 23:48:24 indent right before R.layout.snackbar
Ian Wen 2016/05/18 00:23:46 Done.
+ false);
mAnimationDuration = mView.getResources()
.getInteger(android.R.integer.config_mediumAnimTime);
mMessageView = (TemplatePreservingTextView) mView.findViewById(R.id.snackbar_message);
@@ -77,34 +108,45 @@ class SnackbarView {
}
void show() {
- mParent.addView(mView);
+ if (mParent instanceof CoordinatorLayout) {
+ CoordinatorLayout.LayoutParams lp = (LayoutParams) mView.getLayoutParams();
+ lp.setBehavior(mBehavior);
+ mParent.addView(mView, lp);
+ } else {
+ mParent.addView(mView);
+ }
adjustViewPosition();
mView.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener);
- // Animation, instead of Animator or ViewPropertyAnimator is prefered here because:
- // 1. Animation xml allows specifying 100% as translation, which is much more convenient
- // than waiting for mView to be laid out to get measured height.
- // 2. Animation avoids SurfaceView's clipping issue when doing translating animation.
- Animation fadeIn = AnimationUtils.loadAnimation(mParent.getContext(), R.anim.snackbar_in);
- mView.startAnimation(fadeIn);
+ mView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ mView.removeOnLayoutChangeListener(this);
+ mView.setTranslationY(mView.getHeight());
+ Animator animator = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, 0);
+ animator.setInterpolator(new DecelerateInterpolator());
+ animator.setDuration(mAnimationDuration);
+ startAnimatorOnSurfaceView(animator);
+ }
+ });
}
void dismiss() {
// Disable action button during animation.
mActionButtonView.setEnabled(false);
mView.getViewTreeObserver().removeOnGlobalLayoutListener(mLayoutListener);
- // ViewPropertyAnimator is prefered here because Animation is not canceled when the activity
- // is in backbround.
- mView.animate()
- .alpha(0f)
- .setDuration(mAnimationDuration)
- .setInterpolator(new DecelerateInterpolator())
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mParent.removeView(mView);
- }
- }).start();
+
+ Animator animator = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, mView.getHeight());
+ animator.setInterpolator(new DecelerateInterpolator());
+ animator.setDuration(mAnimationDuration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mParent.removeView(mView);
+ }
+ });
+ startAnimatorOnSurfaceView(animator);
}
void adjustViewPosition() {
@@ -194,6 +236,17 @@ class SnackbarView {
return true;
}
+ /**
+ * Starts the animation with {@link SurfaceView} optimization disabled.
gone 2016/05/17 23:48:24 This comment only applies to the top of the condit
Ian Wen 2016/05/18 00:23:46 Done.
+ */
+ private void startAnimatorOnSurfaceView(Animator animator) {
+ if (mActivity instanceof ChromeActivity) {
+ ((ChromeActivity) mActivity).getWindowAndroid().startAnimationOverContent(animator);
+ } else {
+ animator.start();
+ }
+ }
+
private void setViewText(TextView view, CharSequence text, boolean animate) {
if (view.getText().toString().equals(text)) return;
view.animate().cancel();

Powered by Google App Engine
This is Rietveld 408576698