| Index: chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java
|
| index dac8fbd155857d5f27d1e05f6671668acba72857..babe13a61cd767ce22726b3c6c6344aa471354e4 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java
|
| @@ -15,6 +15,8 @@ import android.content.res.Resources;
|
| import android.view.Gravity;
|
| import android.view.MotionEvent;
|
| import android.view.View;
|
| +import android.view.ViewGroup;
|
| +import android.view.ViewGroup.LayoutParams;
|
| import android.widget.FrameLayout;
|
|
|
| import org.chromium.base.ObserverList;
|
| @@ -22,6 +24,7 @@ import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationListener;
|
|
|
| import java.util.ArrayList;
|
| +import java.util.List;
|
|
|
| /**
|
| * Layout that displays infobars in a stack. Handles all the animations when adding or removing
|
| @@ -112,6 +115,15 @@ public class InfoBarContainerLayout extends FrameLayout {
|
| Resources res = context.getResources();
|
| mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_height);
|
| mFloatingBehavior = new FloatingBehavior(this);
|
| + mBackgroundPeekSize = getResources().getDimensionPixelSize(R.dimen.infobar_compact_size);
|
| + mInfoBarShadowHeight = getResources().getDimensionPixelSize(R.dimen.infobar_shadow_height);
|
| + }
|
| +
|
| + @Override
|
| + public void onAttachedToWindow() {
|
| + super.onAttachedToWindow();
|
| +
|
| + mBottomContainer = (ViewGroup) getRootView().findViewById(R.id.bottom_container);
|
| }
|
|
|
| /**
|
| @@ -175,10 +187,20 @@ public class InfoBarContainerLayout extends FrameLayout {
|
|
|
| // Animation durations.
|
| private static final int DURATION_SLIDE_UP_MS = 250;
|
| + private static final int DURATION_PEEK_MS = 500;
|
| private static final int DURATION_SLIDE_DOWN_MS = 250;
|
| private static final int DURATION_FADE_MS = 100;
|
| private static final int DURATION_FADE_OUT_MS = 200;
|
|
|
| + /** The height that an infobar will peek when being added behind another one. */
|
| + private final int mBackgroundPeekSize;
|
| +
|
| + /** The height of the shadow that sits above the infobar. */
|
| + private final int mInfoBarShadowHeight;
|
| +
|
| + /** The bottom container that the infobar container sits inside of. */
|
| + private ViewGroup mBottomContainer;
|
| +
|
| /**
|
| * Base class for animations inside the InfoBarContainerLayout.
|
| *
|
| @@ -215,11 +237,10 @@ public class InfoBarContainerLayout extends FrameLayout {
|
| * value to endValue and updates the side shadow positions on each frame.
|
| */
|
| ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, float endValue) {
|
| - ValueAnimator animator = ValueAnimator.ofFloat(wrapper.getTranslationY(), endValue);
|
| + ValueAnimator animator = ObjectAnimator.ofFloat(wrapper, View.TRANSLATION_Y, endValue);
|
| animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
| @Override
|
| public void onAnimationUpdate(ValueAnimator animation) {
|
| - wrapper.setTranslationY((float) animation.getAnimatedValue());
|
| mFloatingBehavior.updateShadowPosition();
|
| }
|
| });
|
| @@ -407,9 +428,39 @@ public class InfoBarContainerLayout extends FrameLayout {
|
|
|
| @Override
|
| Animator createAnimator() {
|
| + AnimatorSet set = new AnimatorSet();
|
| + List<Animator> animators = new ArrayList<>();
|
| +
|
| mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight());
|
| - return createTranslationYAnimator(mAppearingWrapper, 0f)
|
| - .setDuration(DURATION_SLIDE_UP_MS);
|
| + mAppearingWrapper.setRestrictHeightForAnimation(true);
|
| + mAppearingWrapper.setHeightForAnimation(mInfoBarShadowHeight + mBackgroundPeekSize);
|
| + mAppearingWrapper.addView(mAppearingWrapper.getItem().getView());
|
| + ValueAnimator animator = createTranslationYAnimator(
|
| + mAppearingWrapper, mBackInfobarHeight - mBackgroundPeekSize);
|
| + animators.add(animator);
|
| +
|
| + animators.add(createTranslationYAnimator(mAppearingWrapper, 0));
|
| +
|
| + // When the infobar container is running this specific animation, do not clip the
|
| + // children so the infobars can animate outside their container.
|
| + set.addListener(new AnimatorListenerAdapter() {
|
| + @Override
|
| + public void onAnimationStart(Animator animation) {
|
| + setHierarchyClipsChildren(false);
|
| + }
|
| +
|
| + @Override
|
| + public void onAnimationEnd(Animator animation) {
|
| + mAppearingWrapper.setRestrictHeightForAnimation(false);
|
| + mAppearingWrapper.removeView(mAppearingWrapper.getItem().getView());
|
| + setHierarchyClipsChildren(true);
|
| + }
|
| + });
|
| +
|
| + set.playSequentially(animators);
|
| + set.setDuration(DURATION_PEEK_MS);
|
| +
|
| + return set;
|
| }
|
|
|
| @Override
|
| @@ -419,6 +470,17 @@ public class InfoBarContainerLayout extends FrameLayout {
|
| }
|
|
|
| /**
|
| + * Used to set the relevant view hierarchy to not clip its children. This is used during
|
| + * animation so views can draw outside the normal bounds.
|
| + * @param clip Whether or not to clip child views.
|
| + */
|
| + private void setHierarchyClipsChildren(boolean clip) {
|
| + setClipChildren(clip);
|
| + ((ViewGroup) getParent()).setClipChildren(clip);
|
| + mBottomContainer.setClipChildren(clip);
|
| + }
|
| +
|
| + /**
|
| * The animation to hide the front infobar and reveal the second-to-front infobar. The front
|
| * infobar slides down and off the screen. The back infobar(s) will adjust to the size of the
|
| * new front infobar, and then the new front infobar's contents will fade in.
|
| @@ -837,7 +899,10 @@ public class InfoBarContainerLayout extends FrameLayout {
|
| protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
| widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec);
|
| super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
| - mFloatingBehavior.afterOnMeasure(getMeasuredHeight());
|
| +
|
| + // Make sure the shadow is tall enough to compensate for the peek animation of other
|
| + // infboars.
|
| + mFloatingBehavior.afterOnMeasure(getMeasuredHeight() + mBackgroundPeekSize);
|
| }
|
|
|
| @Override
|
|
|