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 |