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.widget.FrameLayout; | 18 import android.widget.FrameLayout; |
| 19 | 19 |
| 20 import org.chromium.chrome.R; | 20 import org.chromium.chrome.R; |
| 21 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationList ener; | 21 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationList ener; |
| 22 | 22 |
| 23 import java.util.ArrayList; | 23 import java.util.ArrayList; |
| 24 import java.util.List; | |
| 24 | 25 |
| 25 /** | 26 /** |
| 26 * Layout that displays infobars in a stack. Handles all the animations when add ing or removing | 27 * Layout that displays infobars in a stack. Handles all the animations when add ing or removing |
| 27 * infobars and when swapping infobar contents. | 28 * infobars and when swapping infobar contents. |
| 28 * | 29 * |
| 29 * The first infobar to be added is visible at the front of the stack. Later inf obars peek up just | 30 * The first infobar to be added is visible at the front of the stack. Later inf obars peek up just |
| 30 * enough behind the front infobar to signal their existence; their contents are n't visible at all. | 31 * enough behind the front infobar to signal their existence; their contents are n't visible at all. |
| 31 * The stack has a max depth of three infobars. If additional infobars are added beyond this, they | 32 * The stack has a max depth of three infobars. If additional infobars are added beyond this, they |
| 32 * won't be visible at all until infobars in front of them are dismissed. | 33 * won't be visible at all until infobars in front of them are dismissed. |
| 33 * | 34 * |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 } | 99 } |
| 99 | 100 |
| 100 /** | 101 /** |
| 101 * Creates an empty InfoBarContainerLayout. | 102 * Creates an empty InfoBarContainerLayout. |
| 102 */ | 103 */ |
| 103 InfoBarContainerLayout(Context context) { | 104 InfoBarContainerLayout(Context context) { |
| 104 super(context); | 105 super(context); |
| 105 Resources res = context.getResources(); | 106 Resources res = context.getResources(); |
| 106 mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_h eight); | 107 mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_h eight); |
| 107 mFloatingBehavior = new FloatingBehavior(this); | 108 mFloatingBehavior = new FloatingBehavior(this); |
| 109 mBackgroundPeekSize = getResources().getDimensionPixelSize(R.dimen.min_t ouch_target_size); | |
| 110 | |
| 111 setClipChildren(false); | |
| 108 } | 112 } |
| 109 | 113 |
| 110 /** | 114 /** |
| 111 * Adds an infobar to the container. The infobar appearing animation will ha ppen after the | 115 * Adds an infobar to the container. The infobar appearing animation will ha ppen after the |
| 112 * current animation, if any, finishes. | 116 * current animation, if any, finishes. |
| 113 */ | 117 */ |
| 114 void addInfoBar(Item item) { | 118 void addInfoBar(Item item) { |
| 115 if (item.isLegalDisclosure()) { | 119 if (item.isLegalDisclosure()) { |
| 116 mItems.add(0, item); | 120 mItems.add(0, item); |
| 117 } else { | 121 } else { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 | 158 |
| 155 ///////////////////////////////////////// | 159 ///////////////////////////////////////// |
| 156 // Implementation details | 160 // Implementation details |
| 157 ///////////////////////////////////////// | 161 ///////////////////////////////////////// |
| 158 | 162 |
| 159 /** The maximum number of infobars visible at any time. */ | 163 /** The maximum number of infobars visible at any time. */ |
| 160 private static final int MAX_STACK_DEPTH = 3; | 164 private static final int MAX_STACK_DEPTH = 3; |
| 161 | 165 |
| 162 // Animation durations. | 166 // Animation durations. |
| 163 private static final int DURATION_SLIDE_UP_MS = 250; | 167 private static final int DURATION_SLIDE_UP_MS = 250; |
| 168 private static final int DURATION_PEEK_MS = 500; | |
| 164 private static final int DURATION_SLIDE_DOWN_MS = 250; | 169 private static final int DURATION_SLIDE_DOWN_MS = 250; |
| 165 private static final int DURATION_FADE_MS = 100; | 170 private static final int DURATION_FADE_MS = 100; |
| 166 private static final int DURATION_FADE_OUT_MS = 200; | 171 private static final int DURATION_FADE_OUT_MS = 200; |
| 167 | 172 |
| 173 // The height that an infobar will peek when being added behind another one. | |
| 174 private final int mBackgroundPeekSize; | |
| 175 | |
| 168 /** | 176 /** |
| 169 * Base class for animations inside the InfoBarContainerLayout. | 177 * Base class for animations inside the InfoBarContainerLayout. |
| 170 * | 178 * |
| 171 * Provides a standardized way to prepare for, run, and clean up after anima tions. Each subclass | 179 * Provides a standardized way to prepare for, run, and clean up after anima tions. Each subclass |
| 172 * should implement prepareAnimation(), createAnimator(), and onAnimationEnd () as needed. | 180 * should implement prepareAnimation(), createAnimator(), and onAnimationEnd () as needed. |
| 173 */ | 181 */ |
| 174 private abstract class InfoBarAnimation { | 182 private abstract class InfoBarAnimation { |
| 175 private Animator mAnimator; | 183 private Animator mAnimator; |
| 176 | 184 |
| 177 final boolean isStarted() { | 185 final boolean isStarted() { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 194 mAnimator = createAnimator(); | 202 mAnimator = createAnimator(); |
| 195 mAnimator.addListener(listener); | 203 mAnimator.addListener(listener); |
| 196 mAnimator.start(); | 204 mAnimator.start(); |
| 197 } | 205 } |
| 198 | 206 |
| 199 /** | 207 /** |
| 200 * Returns an animator that animates an InfoBarWrapper's y-translation f rom its current | 208 * Returns an animator that animates an InfoBarWrapper's y-translation f rom its current |
| 201 * value to endValue and updates the side shadow positions on each frame . | 209 * value to endValue and updates the side shadow positions on each frame . |
| 202 */ | 210 */ |
| 203 ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, f loat endValue) { | 211 ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, f loat endValue) { |
| 204 ValueAnimator animator = ValueAnimator.ofFloat(wrapper.getTranslatio nY(), endValue); | 212 ValueAnimator animator = ObjectAnimator.ofFloat(wrapper, View.TRANSL ATION_Y, endValue); |
| 205 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener( ) { | 213 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener( ) { |
| 206 @Override | 214 @Override |
| 207 public void onAnimationUpdate(ValueAnimator animation) { | 215 public void onAnimationUpdate(ValueAnimator animation) { |
| 208 wrapper.setTranslationY((float) animation.getAnimatedValue() ); | |
| 209 mFloatingBehavior.updateShadowPosition(); | 216 mFloatingBehavior.updateShadowPosition(); |
| 210 } | 217 } |
| 211 }); | 218 }); |
| 212 return animator; | 219 return animator; |
| 213 } | 220 } |
| 214 | 221 |
| 215 /** | 222 /** |
| 216 * Called before the animation begins. This is the time to add views to the hierarchy and | 223 * Called before the animation begins. This is the time to add views to the hierarchy and |
| 217 * adjust layout parameters. | 224 * adjust layout parameters. |
| 218 */ | 225 */ |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 | 384 |
| 378 /** | 385 /** |
| 379 * The animation to show a back infobar. The infobar slides up behind the ex isting infobars, so | 386 * The animation to show a back infobar. The infobar slides up behind the ex isting infobars, so |
| 380 * its top edge peeks out just a bit. | 387 * its top edge peeks out just a bit. |
| 381 */ | 388 */ |
| 382 private class BackInfoBarAppearingAnimation extends InfoBarAnimation { | 389 private class BackInfoBarAppearingAnimation extends InfoBarAnimation { |
| 383 private InfoBarWrapper mAppearingWrapper; | 390 private InfoBarWrapper mAppearingWrapper; |
| 384 | 391 |
| 385 BackInfoBarAppearingAnimation(Item appearingItem) { | 392 BackInfoBarAppearingAnimation(Item appearingItem) { |
| 386 mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); | 393 mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); |
| 394 mAppearingWrapper.addView(appearingItem.getView()); | |
| 387 } | 395 } |
| 388 | 396 |
| 389 @Override | 397 @Override |
| 390 void prepareAnimation() { | 398 void prepareAnimation() { |
| 391 addWrapper(mAppearingWrapper); | 399 addWrapper(mAppearingWrapper); |
| 392 } | 400 } |
| 393 | 401 |
| 394 @Override | 402 @Override |
| 395 Animator createAnimator() { | 403 Animator createAnimator() { |
| 404 AnimatorSet set = new AnimatorSet(); | |
| 405 List<Animator> animators = new ArrayList<>(); | |
| 406 | |
| 396 mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight()); | 407 mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight()); |
| 397 return createTranslationYAnimator(mAppearingWrapper, 0f) | 408 ValueAnimator animator = |
| 398 .setDuration(DURATION_SLIDE_UP_MS); | 409 createTranslationYAnimator(mAppearingWrapper, -mBackgroundPe ekSize); |
| 410 animator.setDuration(DURATION_PEEK_MS); | |
|
Ted C
2017/05/17 17:55:54
We should be able to set the duration on the set s
mdjones
2017/05/17 21:05:19
Setting duration on the set ends up working just f
| |
| 411 animators.add(animator); | |
| 412 | |
| 413 animators.add( | |
| 414 createTranslationYAnimator(mAppearingWrapper, 0).setDuration (DURATION_PEEK_MS)); | |
| 415 | |
| 416 set.addListener(new AnimatorListenerAdapter() { | |
|
Ted C
2017/05/17 17:55:54
Do you want the view to be removed even if the set
mdjones
2017/05/17 21:05:19
When cancel is called on the animator set, cancel
| |
| 417 @Override | |
| 418 public void onAnimationEnd(Animator animation) { | |
| 419 mAppearingWrapper.removeView(mAppearingWrapper.getItem().get View()); | |
| 420 } | |
| 421 }); | |
| 422 | |
| 423 set.playSequentially(animators); | |
| 424 | |
| 425 return set; | |
| 399 } | 426 } |
| 400 | 427 |
| 401 @Override | 428 @Override |
| 402 int getAnimationType() { | 429 int getAnimationType() { |
| 403 return InfoBarAnimationListener.ANIMATION_TYPE_SHOW; | 430 return InfoBarAnimationListener.ANIMATION_TYPE_SHOW; |
| 404 } | 431 } |
| 405 } | 432 } |
| 406 | 433 |
| 407 /** | 434 /** |
| 408 * The animation to hide the front infobar and reveal the second-to-front in fobar. The front | 435 * The animation to hide the front infobar and reveal the second-to-front in fobar. The front |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 LayoutParams lp = (LayoutParams) child.getLayoutParams(); | 835 LayoutParams lp = (LayoutParams) child.getLayoutParams(); |
| 809 lp.topMargin = (childCount - 1 - i) * mBackInfobarHeight; | 836 lp.topMargin = (childCount - 1 - i) * mBackInfobarHeight; |
| 810 child.setLayoutParams(lp); | 837 child.setLayoutParams(lp); |
| 811 } | 838 } |
| 812 } | 839 } |
| 813 | 840 |
| 814 @Override | 841 @Override |
| 815 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | 842 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 816 widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec); | 843 widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec); |
| 817 super.onMeasure(widthMeasureSpec, heightMeasureSpec); | 844 super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| 818 mFloatingBehavior.afterOnMeasure(getMeasuredHeight()); | 845 |
| 846 // Make sure the shadow is tall enough to compensate for the peek animat ion of other | |
| 847 // infboars. | |
| 848 mFloatingBehavior.afterOnMeasure(getMeasuredHeight() + mBackgroundPeekSi ze); | |
| 819 } | 849 } |
| 820 | 850 |
| 821 @Override | 851 @Override |
| 822 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) { | 852 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) { |
| 823 super.onLayout(changed, left, top, right, bottom); | 853 super.onLayout(changed, left, top, right, bottom); |
| 824 mFloatingBehavior.updateShadowPosition(); | 854 mFloatingBehavior.updateShadowPosition(); |
| 825 | 855 |
| 826 // Animations start after a layout has completed, at which point all vie ws are guaranteed | 856 // Animations start after a layout has completed, at which point all vie ws are guaranteed |
| 827 // to have valid sizes and positions. | 857 // to have valid sizes and positions. |
| 828 if (mAnimation != null && !mAnimation.isStarted()) { | 858 if (mAnimation != null && !mAnimation.isStarted()) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 848 | 878 |
| 849 @Override | 879 @Override |
| 850 public boolean onHoverEvent(MotionEvent event) { | 880 public boolean onHoverEvent(MotionEvent event) { |
| 851 super.onHoverEvent(event); | 881 super.onHoverEvent(event); |
| 852 // Consume all hover events so they do not reach the ContentView. In tou ch exploration mode, | 882 // Consume all hover events so they do not reach the ContentView. In tou ch exploration mode, |
| 853 // this prevents the user from interacting with the part of the ContentV iew behind the | 883 // this prevents the user from interacting with the part of the ContentV iew behind the |
| 854 // infobars. http://crbug.com/430701 | 884 // infobars. http://crbug.com/430701 |
| 855 return true; | 885 return true; |
| 856 } | 886 } |
| 857 } | 887 } |
| OLD | NEW |