Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.infobar; | 5 package org.chromium.chrome.browser.infobar; |
| 6 | 6 |
| 7 import android.animation.Animator; | 7 import android.animation.Animator; |
| 8 import android.animation.AnimatorListenerAdapter; | 8 import android.animation.AnimatorListenerAdapter; |
| 9 import android.animation.AnimatorSet; | 9 import android.animation.AnimatorSet; |
| 10 import android.animation.ObjectAnimator; | 10 import android.animation.ObjectAnimator; |
| 11 import android.animation.ValueAnimator; | 11 import android.animation.ValueAnimator; |
| 12 import android.annotation.SuppressLint; | 12 import android.annotation.SuppressLint; |
| 13 import android.content.Context; | 13 import android.content.Context; |
| 14 import android.content.res.Resources; | 14 import android.content.res.Resources; |
| 15 import android.view.Gravity; | 15 import android.view.Gravity; |
| 16 import android.view.MotionEvent; | 16 import android.view.MotionEvent; |
| 17 import android.view.View; | 17 import android.view.View; |
| 18 import android.view.ViewGroup; | |
| 19 import android.view.ViewGroup.LayoutParams; | |
| 18 import android.widget.FrameLayout; | 20 import android.widget.FrameLayout; |
| 19 | 21 |
| 20 import org.chromium.base.ObserverList; | 22 import org.chromium.base.ObserverList; |
| 21 import org.chromium.chrome.R; | 23 import org.chromium.chrome.R; |
| 22 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationList ener; | 24 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationList ener; |
| 23 | 25 |
| 24 import java.util.ArrayList; | 26 import java.util.ArrayList; |
| 27 import java.util.List; | |
| 25 | 28 |
| 26 /** | 29 /** |
| 27 * Layout that displays infobars in a stack. Handles all the animations when add ing or removing | 30 * Layout that displays infobars in a stack. Handles all the animations when add ing or removing |
| 28 * infobars and when swapping infobar contents. | 31 * infobars and when swapping infobar contents. |
| 29 * | 32 * |
| 30 * The first infobar to be added is visible at the front of the stack. Later inf obars peek up just | 33 * The first infobar to be added is visible at the front of the stack. Later inf obars peek up just |
| 31 * enough behind the front infobar to signal their existence; their contents are n't visible at all. | 34 * enough behind the front infobar to signal their existence; their contents are n't visible at all. |
| 32 * The stack has a max depth of three infobars. If additional infobars are added beyond this, they | 35 * The stack has a max depth of three infobars. If additional infobars are added beyond this, they |
| 33 * won't be visible at all until infobars in front of them are dismissed. | 36 * won't be visible at all until infobars in front of them are dismissed. |
| 34 * | 37 * |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 } | 108 } |
| 106 | 109 |
| 107 /** | 110 /** |
| 108 * Creates an empty InfoBarContainerLayout. | 111 * Creates an empty InfoBarContainerLayout. |
| 109 */ | 112 */ |
| 110 InfoBarContainerLayout(Context context) { | 113 InfoBarContainerLayout(Context context) { |
| 111 super(context); | 114 super(context); |
| 112 Resources res = context.getResources(); | 115 Resources res = context.getResources(); |
| 113 mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_h eight); | 116 mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_h eight); |
| 114 mFloatingBehavior = new FloatingBehavior(this); | 117 mFloatingBehavior = new FloatingBehavior(this); |
| 118 mBackgroundPeekSize = getResources().getDimensionPixelSize(R.dimen.infob ar_compact_size); | |
| 119 mInfoBarShadowHeight = getResources().getDimensionPixelSize(R.dimen.info bar_shadow_height); | |
| 120 } | |
| 121 | |
| 122 @Override | |
| 123 public void onAttachedToWindow() { | |
| 124 super.onAttachedToWindow(); | |
| 125 | |
| 126 mBottomContainer = (ViewGroup) getRootView().findViewById(R.id.bottom_co ntainer); | |
| 115 } | 127 } |
| 116 | 128 |
| 117 /** | 129 /** |
| 118 * Adds an infobar to the container. The infobar appearing animation will ha ppen after the | 130 * Adds an infobar to the container. The infobar appearing animation will ha ppen after the |
| 119 * current animation, if any, finishes. | 131 * current animation, if any, finishes. |
| 120 */ | 132 */ |
| 121 void addInfoBar(Item item) { | 133 void addInfoBar(Item item) { |
| 122 if (item.isLegalDisclosure()) { | 134 if (item.isLegalDisclosure()) { |
| 123 mItems.add(0, item); | 135 mItems.add(0, item); |
| 124 } else { | 136 } else { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 | 180 |
| 169 ///////////////////////////////////////// | 181 ///////////////////////////////////////// |
| 170 // Implementation details | 182 // Implementation details |
| 171 ///////////////////////////////////////// | 183 ///////////////////////////////////////// |
| 172 | 184 |
| 173 /** The maximum number of infobars visible at any time. */ | 185 /** The maximum number of infobars visible at any time. */ |
| 174 private static final int MAX_STACK_DEPTH = 3; | 186 private static final int MAX_STACK_DEPTH = 3; |
| 175 | 187 |
| 176 // Animation durations. | 188 // Animation durations. |
| 177 private static final int DURATION_SLIDE_UP_MS = 250; | 189 private static final int DURATION_SLIDE_UP_MS = 250; |
| 190 private static final int DURATION_PEEK_MS = 500; | |
| 178 private static final int DURATION_SLIDE_DOWN_MS = 250; | 191 private static final int DURATION_SLIDE_DOWN_MS = 250; |
| 179 private static final int DURATION_FADE_MS = 100; | 192 private static final int DURATION_FADE_MS = 100; |
| 180 private static final int DURATION_FADE_OUT_MS = 200; | 193 private static final int DURATION_FADE_OUT_MS = 200; |
| 181 | 194 |
| 195 /** The height that an infobar will peek when being added behind another one . */ | |
| 196 private final int mBackgroundPeekSize; | |
| 197 | |
| 198 /** The height of the shadow that sits above the infobar. */ | |
| 199 private final int mInfoBarShadowHeight; | |
| 200 | |
| 201 /** The bottom container that the infobar container sits inside of. */ | |
| 202 private ViewGroup mBottomContainer; | |
| 203 | |
| 182 /** | 204 /** |
| 183 * Base class for animations inside the InfoBarContainerLayout. | 205 * Base class for animations inside the InfoBarContainerLayout. |
| 184 * | 206 * |
| 185 * Provides a standardized way to prepare for, run, and clean up after anima tions. Each subclass | 207 * Provides a standardized way to prepare for, run, and clean up after anima tions. Each subclass |
| 186 * should implement prepareAnimation(), createAnimator(), and onAnimationEnd () as needed. | 208 * should implement prepareAnimation(), createAnimator(), and onAnimationEnd () as needed. |
| 187 */ | 209 */ |
| 188 private abstract class InfoBarAnimation { | 210 private abstract class InfoBarAnimation { |
| 189 private Animator mAnimator; | 211 private Animator mAnimator; |
| 190 | 212 |
| 191 final boolean isStarted() { | 213 final boolean isStarted() { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 208 mAnimator = createAnimator(); | 230 mAnimator = createAnimator(); |
| 209 mAnimator.addListener(listener); | 231 mAnimator.addListener(listener); |
| 210 mAnimator.start(); | 232 mAnimator.start(); |
| 211 } | 233 } |
| 212 | 234 |
| 213 /** | 235 /** |
| 214 * Returns an animator that animates an InfoBarWrapper's y-translation f rom its current | 236 * Returns an animator that animates an InfoBarWrapper's y-translation f rom its current |
| 215 * value to endValue and updates the side shadow positions on each frame . | 237 * value to endValue and updates the side shadow positions on each frame . |
| 216 */ | 238 */ |
| 217 ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, f loat endValue) { | 239 ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, f loat endValue) { |
| 218 ValueAnimator animator = ValueAnimator.ofFloat(wrapper.getTranslatio nY(), endValue); | 240 ValueAnimator animator = ObjectAnimator.ofFloat(wrapper, View.TRANSL ATION_Y, endValue); |
| 219 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener( ) { | 241 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener( ) { |
| 220 @Override | 242 @Override |
| 221 public void onAnimationUpdate(ValueAnimator animation) { | 243 public void onAnimationUpdate(ValueAnimator animation) { |
| 222 wrapper.setTranslationY((float) animation.getAnimatedValue() ); | |
| 223 mFloatingBehavior.updateShadowPosition(); | 244 mFloatingBehavior.updateShadowPosition(); |
| 224 } | 245 } |
| 225 }); | 246 }); |
| 226 return animator; | 247 return animator; |
| 227 } | 248 } |
| 228 | 249 |
| 229 /** | 250 /** |
| 230 * Called before the animation begins. This is the time to add views to the hierarchy and | 251 * Called before the animation begins. This is the time to add views to the hierarchy and |
| 231 * adjust layout parameters. | 252 * adjust layout parameters. |
| 232 */ | 253 */ |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 | 412 |
| 392 /** | 413 /** |
| 393 * The animation to show a back infobar. The infobar slides up behind the ex isting infobars, so | 414 * The animation to show a back infobar. The infobar slides up behind the ex isting infobars, so |
| 394 * its top edge peeks out just a bit. | 415 * its top edge peeks out just a bit. |
| 395 */ | 416 */ |
| 396 private class BackInfoBarAppearingAnimation extends InfoBarAnimation { | 417 private class BackInfoBarAppearingAnimation extends InfoBarAnimation { |
| 397 private InfoBarWrapper mAppearingWrapper; | 418 private InfoBarWrapper mAppearingWrapper; |
| 398 | 419 |
| 399 BackInfoBarAppearingAnimation(Item appearingItem) { | 420 BackInfoBarAppearingAnimation(Item appearingItem) { |
| 400 mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); | 421 mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); |
| 422 mAppearingWrapper.addView(appearingItem.getView()); | |
| 401 } | 423 } |
| 402 | 424 |
| 403 @Override | 425 @Override |
| 404 void prepareAnimation() { | 426 void prepareAnimation() { |
| 405 addWrapper(mAppearingWrapper); | 427 addWrapper(mAppearingWrapper); |
| 406 } | 428 } |
| 407 | 429 |
| 408 @Override | 430 @Override |
| 409 Animator createAnimator() { | 431 Animator createAnimator() { |
| 432 AnimatorSet set = new AnimatorSet(); | |
| 433 List<Animator> animators = new ArrayList<>(); | |
| 434 | |
| 410 mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight()); | 435 mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight()); |
| 411 return createTranslationYAnimator(mAppearingWrapper, 0f) | 436 mAppearingWrapper.setHeightForAnimation(mInfoBarShadowHeight + mBack groundPeekSize); |
| 412 .setDuration(DURATION_SLIDE_UP_MS); | 437 ValueAnimator animator = createTranslationYAnimator( |
| 438 mAppearingWrapper, mInfoBarShadowHeight - mBackgroundPeekSiz e); | |
| 439 animators.add(animator); | |
| 440 | |
| 441 animators.add(createTranslationYAnimator(mAppearingWrapper, 0)); | |
| 442 | |
| 443 // When the infobar container is running this specific animation, do not clip the | |
| 444 // children so the infobars can animate outside their container. | |
| 445 set.addListener(new AnimatorListenerAdapter() { | |
| 446 @Override | |
| 447 public void onAnimationStart(Animator animation) { | |
| 448 mAppearingWrapper.setRestrictHeightForAnimation(true); | |
| 449 setHierarchyClipsChildren(false); | |
| 450 } | |
| 451 | |
| 452 @Override | |
| 453 public void onAnimationEnd(Animator animation) { | |
| 454 mAppearingWrapper.setRestrictHeightForAnimation(false); | |
| 455 mAppearingWrapper.removeView(mAppearingWrapper.getItem().get View()); | |
|
Ted C
2017/05/19 17:21:41
do we need to do this anymore?
mdjones
2017/05/19 17:30:14
Technically no. Prior to this change the content w
| |
| 456 setHierarchyClipsChildren(true); | |
| 457 } | |
| 458 }); | |
| 459 | |
| 460 set.playSequentially(animators); | |
| 461 set.setDuration(DURATION_PEEK_MS); | |
| 462 | |
| 463 return set; | |
| 413 } | 464 } |
| 414 | 465 |
| 415 @Override | 466 @Override |
| 416 int getAnimationType() { | 467 int getAnimationType() { |
| 417 return InfoBarAnimationListener.ANIMATION_TYPE_SHOW; | 468 return InfoBarAnimationListener.ANIMATION_TYPE_SHOW; |
| 418 } | 469 } |
| 419 } | 470 } |
| 420 | 471 |
| 421 /** | 472 /** |
| 473 * Used to set the relevant view hierarchy to not clip its children. This is used during | |
| 474 * animation so views can draw outside the normal bounds. | |
| 475 * @param clip Whether or not to clip child views. | |
| 476 */ | |
| 477 private void setHierarchyClipsChildren(boolean clip) { | |
| 478 setClipChildren(clip); | |
| 479 ((ViewGroup) getParent()).setClipChildren(clip); | |
| 480 mBottomContainer.setClipChildren(clip); | |
| 481 } | |
| 482 | |
| 483 /** | |
| 422 * The animation to hide the front infobar and reveal the second-to-front in fobar. The front | 484 * The animation to hide the front infobar and reveal the second-to-front in fobar. The front |
| 423 * infobar slides down and off the screen. The back infobar(s) will adjust t o the size of the | 485 * infobar slides down and off the screen. The back infobar(s) will adjust t o the size of the |
| 424 * new front infobar, and then the new front infobar's contents will fade in . | 486 * new front infobar, and then the new front infobar's contents will fade in . |
| 425 */ | 487 */ |
| 426 private class FrontInfoBarDisappearingAndRevealingAnimation extends InfoBarA nimation { | 488 private class FrontInfoBarDisappearingAndRevealingAnimation extends InfoBarA nimation { |
| 427 private InfoBarWrapper mOldFrontWrapper; | 489 private InfoBarWrapper mOldFrontWrapper; |
| 428 private InfoBarWrapper mNewFrontWrapper; | 490 private InfoBarWrapper mNewFrontWrapper; |
| 429 private View mNewFrontContents; | 491 private View mNewFrontContents; |
| 430 | 492 |
| 431 @Override | 493 @Override |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 LayoutParams lp = (LayoutParams) child.getLayoutParams(); | 892 LayoutParams lp = (LayoutParams) child.getLayoutParams(); |
| 831 lp.topMargin = (childCount - 1 - i) * mBackInfobarHeight; | 893 lp.topMargin = (childCount - 1 - i) * mBackInfobarHeight; |
| 832 child.setLayoutParams(lp); | 894 child.setLayoutParams(lp); |
| 833 } | 895 } |
| 834 } | 896 } |
| 835 | 897 |
| 836 @Override | 898 @Override |
| 837 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | 899 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 838 widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec); | 900 widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec); |
| 839 super.onMeasure(widthMeasureSpec, heightMeasureSpec); | 901 super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| 840 mFloatingBehavior.afterOnMeasure(getMeasuredHeight()); | 902 |
| 903 // Make sure the shadow is tall enough to compensate for the peek animat ion of other | |
| 904 // infboars. | |
| 905 mFloatingBehavior.afterOnMeasure(getMeasuredHeight() + mBackgroundPeekSi ze); | |
| 841 } | 906 } |
| 842 | 907 |
| 843 @Override | 908 @Override |
| 844 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) { | 909 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) { |
| 845 super.onLayout(changed, left, top, right, bottom); | 910 super.onLayout(changed, left, top, right, bottom); |
| 846 mFloatingBehavior.updateShadowPosition(); | 911 mFloatingBehavior.updateShadowPosition(); |
| 847 | 912 |
| 848 // Animations start after a layout has completed, at which point all vie ws are guaranteed | 913 // Animations start after a layout has completed, at which point all vie ws are guaranteed |
| 849 // to have valid sizes and positions. | 914 // to have valid sizes and positions. |
| 850 if (mAnimation != null && !mAnimation.isStarted()) { | 915 if (mAnimation != null && !mAnimation.isStarted()) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 870 | 935 |
| 871 @Override | 936 @Override |
| 872 public boolean onHoverEvent(MotionEvent event) { | 937 public boolean onHoverEvent(MotionEvent event) { |
| 873 super.onHoverEvent(event); | 938 super.onHoverEvent(event); |
| 874 // Consume all hover events so they do not reach the ContentView. In tou ch exploration mode, | 939 // Consume all hover events so they do not reach the ContentView. In tou ch exploration mode, |
| 875 // this prevents the user from interacting with the part of the ContentV iew behind the | 940 // this prevents the user from interacting with the part of the ContentV iew behind the |
| 876 // infobars. http://crbug.com/430701 | 941 // infobars. http://crbug.com/430701 |
| 877 return true; | 942 return true; |
| 878 } | 943 } |
| 879 } | 944 } |
| OLD | NEW |