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

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: rebase 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 f30964fb53febd22e7f2439bf5cd9f15a0a374d0..008f269a6f5970a15d8c310513015c67c892da00 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,37 @@ class SnackbarView {
};
/**
+ * Behavior that intercepts touch event from the CompositorViewHoder.
+ */
+ private final Behavior<View> mBehavior = new Behavior<View>() {
+ @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}.
- * @param parent The main view of the embedding Activity.
+ * @param activity The activity that displays the snackbar.
* @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 = findParentView(activity);
+ mView = (ViewGroup) LayoutInflater.from(activity).inflate(
+ R.layout.snackbar, mParent, false);
mAnimationDuration = mView.getResources()
.getInteger(android.R.integer.config_mediumAnimTime);
mMessageView = (TemplatePreservingTextView) mView.findViewById(R.id.snackbar_message);
@@ -77,34 +106,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() {
@@ -195,6 +235,30 @@ class SnackbarView {
return true;
}
+ /**
+ * @return The parent {@link ViewGroup} that {@link #mView} will be added to.
+ */
+ private ViewGroup findParentView(Activity activity) {
+ if (activity instanceof ChromeActivity) {
+ return ((ChromeActivity) activity).getCompositorViewHolder();
+ } else {
+ return (ViewGroup) activity.findViewById(android.R.id.content);
+ }
+ }
+
+ /**
+ * Starts the {@link Animator} with {@link SurfaceView} optimization disabled. If a
+ * {@link SurfaceView} is not present in the given {@link Activity}, start the {@link Animator}
+ * in the normal way.
+ */
+ 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