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; | |
18 import android.widget.FrameLayout; | 19 import android.widget.FrameLayout; |
19 | 20 |
20 import org.chromium.base.ObserverList; | 21 import org.chromium.base.ObserverList; |
21 import org.chromium.chrome.R; | 22 import org.chromium.chrome.R; |
22 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationList ener; | 23 import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationList ener; |
23 | 24 |
24 import java.util.ArrayList; | 25 import java.util.ArrayList; |
26 import java.util.List; | |
25 | 27 |
26 /** | 28 /** |
27 * Layout that displays infobars in a stack. Handles all the animations when add ing or removing | 29 * Layout that displays infobars in a stack. Handles all the animations when add ing or removing |
28 * infobars and when swapping infobar contents. | 30 * infobars and when swapping infobar contents. |
29 * | 31 * |
30 * The first infobar to be added is visible at the front of the stack. Later inf obars peek up just | 32 * 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. | 33 * 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 | 34 * 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. | 35 * won't be visible at all until infobars in front of them are dismissed. |
34 * | 36 * |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 } | 107 } |
106 | 108 |
107 /** | 109 /** |
108 * Creates an empty InfoBarContainerLayout. | 110 * Creates an empty InfoBarContainerLayout. |
109 */ | 111 */ |
110 InfoBarContainerLayout(Context context) { | 112 InfoBarContainerLayout(Context context) { |
111 super(context); | 113 super(context); |
112 Resources res = context.getResources(); | 114 Resources res = context.getResources(); |
113 mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_h eight); | 115 mBackInfobarHeight = res.getDimensionPixelSize(R.dimen.infobar_peeking_h eight); |
114 mFloatingBehavior = new FloatingBehavior(this); | 116 mFloatingBehavior = new FloatingBehavior(this); |
117 mBackgroundPeekSize = getResources().getDimensionPixelSize(R.dimen.min_t ouch_target_size); | |
118 | |
119 setClipChildren(false); | |
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 bottom container that the infobar container sits inside of. */ | |
199 private ViewGroup mBottomContainer; | |
200 | |
182 /** | 201 /** |
183 * Base class for animations inside the InfoBarContainerLayout. | 202 * Base class for animations inside the InfoBarContainerLayout. |
184 * | 203 * |
185 * Provides a standardized way to prepare for, run, and clean up after anima tions. Each subclass | 204 * 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. | 205 * should implement prepareAnimation(), createAnimator(), and onAnimationEnd () as needed. |
187 */ | 206 */ |
188 private abstract class InfoBarAnimation { | 207 private abstract class InfoBarAnimation { |
189 private Animator mAnimator; | 208 private Animator mAnimator; |
190 | 209 |
191 final boolean isStarted() { | 210 final boolean isStarted() { |
(...skipping 16 matching lines...) Expand all Loading... | |
208 mAnimator = createAnimator(); | 227 mAnimator = createAnimator(); |
209 mAnimator.addListener(listener); | 228 mAnimator.addListener(listener); |
210 mAnimator.start(); | 229 mAnimator.start(); |
211 } | 230 } |
212 | 231 |
213 /** | 232 /** |
214 * Returns an animator that animates an InfoBarWrapper's y-translation f rom its current | 233 * 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 . | 234 * value to endValue and updates the side shadow positions on each frame . |
216 */ | 235 */ |
217 ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, f loat endValue) { | 236 ValueAnimator createTranslationYAnimator(final InfoBarWrapper wrapper, f loat endValue) { |
218 ValueAnimator animator = ValueAnimator.ofFloat(wrapper.getTranslatio nY(), endValue); | 237 ValueAnimator animator = ObjectAnimator.ofFloat(wrapper, View.TRANSL ATION_Y, endValue); |
219 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener( ) { | 238 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener( ) { |
220 @Override | 239 @Override |
221 public void onAnimationUpdate(ValueAnimator animation) { | 240 public void onAnimationUpdate(ValueAnimator animation) { |
222 wrapper.setTranslationY((float) animation.getAnimatedValue() ); | |
223 mFloatingBehavior.updateShadowPosition(); | 241 mFloatingBehavior.updateShadowPosition(); |
224 } | 242 } |
225 }); | 243 }); |
226 return animator; | 244 return animator; |
227 } | 245 } |
228 | 246 |
229 /** | 247 /** |
230 * Called before the animation begins. This is the time to add views to the hierarchy and | 248 * Called before the animation begins. This is the time to add views to the hierarchy and |
231 * adjust layout parameters. | 249 * adjust layout parameters. |
232 */ | 250 */ |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 | 409 |
392 /** | 410 /** |
393 * The animation to show a back infobar. The infobar slides up behind the ex isting infobars, so | 411 * 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. | 412 * its top edge peeks out just a bit. |
395 */ | 413 */ |
396 private class BackInfoBarAppearingAnimation extends InfoBarAnimation { | 414 private class BackInfoBarAppearingAnimation extends InfoBarAnimation { |
397 private InfoBarWrapper mAppearingWrapper; | 415 private InfoBarWrapper mAppearingWrapper; |
398 | 416 |
399 BackInfoBarAppearingAnimation(Item appearingItem) { | 417 BackInfoBarAppearingAnimation(Item appearingItem) { |
400 mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); | 418 mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); |
419 mAppearingWrapper.addView(appearingItem.getView()); | |
401 } | 420 } |
402 | 421 |
403 @Override | 422 @Override |
404 void prepareAnimation() { | 423 void prepareAnimation() { |
405 addWrapper(mAppearingWrapper); | 424 addWrapper(mAppearingWrapper); |
406 } | 425 } |
407 | 426 |
408 @Override | 427 @Override |
409 Animator createAnimator() { | 428 Animator createAnimator() { |
429 AnimatorSet set = new AnimatorSet(); | |
430 List<Animator> animators = new ArrayList<>(); | |
431 | |
410 mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight()); | 432 mAppearingWrapper.setTranslationY(mAppearingWrapper.getHeight()); |
411 return createTranslationYAnimator(mAppearingWrapper, 0f) | 433 ValueAnimator animator = |
412 .setDuration(DURATION_SLIDE_UP_MS); | 434 createTranslationYAnimator(mAppearingWrapper, -mBackgroundPe ekSize); |
435 animators.add(animator); | |
436 | |
437 animators.add(createTranslationYAnimator(mAppearingWrapper, 0)); | |
438 | |
439 set.addListener(new AnimatorListenerAdapter() { | |
Ted C
2017/05/18 00:09:29
merge with the one below?
mdjones
2017/05/18 17:40:13
Whoops. Done.
| |
440 @Override | |
441 public void onAnimationEnd(Animator animation) { | |
442 mAppearingWrapper.removeView(mAppearingWrapper.getItem().get View()); | |
443 } | |
444 }); | |
445 | |
446 set.playSequentially(animators); | |
447 set.setDuration(DURATION_PEEK_MS); | |
448 | |
449 // When the infobar container is running this specific animation, do not clip the | |
450 // children so the infobars can animate outside their container. | |
451 set.addListener(new AnimatorListenerAdapter() { | |
452 @Override | |
453 public void onAnimationStart(Animator animation) { | |
454 mBottomContainer.setClipChildren(false); | |
Ted C
2017/05/18 00:09:29
should we also set setClipChildren on the InfobarC
mdjones
2017/05/18 17:40:13
Added utility method that sets this value in all t
| |
455 } | |
456 | |
457 @Override | |
458 public void onAnimationEnd(Animator animation) { | |
459 mBottomContainer.setClipChildren(true); | |
460 } | |
461 }); | |
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 /** |
422 * The animation to hide the front infobar and reveal the second-to-front in fobar. The front | 473 * The animation to hide the front infobar and reveal the second-to-front in fobar. The front |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
830 LayoutParams lp = (LayoutParams) child.getLayoutParams(); | 881 LayoutParams lp = (LayoutParams) child.getLayoutParams(); |
831 lp.topMargin = (childCount - 1 - i) * mBackInfobarHeight; | 882 lp.topMargin = (childCount - 1 - i) * mBackInfobarHeight; |
832 child.setLayoutParams(lp); | 883 child.setLayoutParams(lp); |
833 } | 884 } |
834 } | 885 } |
835 | 886 |
836 @Override | 887 @Override |
837 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | 888 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
838 widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec); | 889 widthMeasureSpec = mFloatingBehavior.beforeOnMeasure(widthMeasureSpec); |
839 super.onMeasure(widthMeasureSpec, heightMeasureSpec); | 890 super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
840 mFloatingBehavior.afterOnMeasure(getMeasuredHeight()); | 891 |
892 // Make sure the shadow is tall enough to compensate for the peek animat ion of other | |
893 // infboars. | |
894 mFloatingBehavior.afterOnMeasure(getMeasuredHeight() + mBackgroundPeekSi ze); | |
841 } | 895 } |
842 | 896 |
843 @Override | 897 @Override |
844 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) { | 898 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) { |
845 super.onLayout(changed, left, top, right, bottom); | 899 super.onLayout(changed, left, top, right, bottom); |
846 mFloatingBehavior.updateShadowPosition(); | 900 mFloatingBehavior.updateShadowPosition(); |
847 | 901 |
848 // Animations start after a layout has completed, at which point all vie ws are guaranteed | 902 // Animations start after a layout has completed, at which point all vie ws are guaranteed |
849 // to have valid sizes and positions. | 903 // to have valid sizes and positions. |
850 if (mAnimation != null && !mAnimation.isStarted()) { | 904 if (mAnimation != null && !mAnimation.isStarted()) { |
(...skipping 19 matching lines...) Expand all Loading... | |
870 | 924 |
871 @Override | 925 @Override |
872 public boolean onHoverEvent(MotionEvent event) { | 926 public boolean onHoverEvent(MotionEvent event) { |
873 super.onHoverEvent(event); | 927 super.onHoverEvent(event); |
874 // Consume all hover events so they do not reach the ContentView. In tou ch exploration mode, | 928 // 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 | 929 // this prevents the user from interacting with the part of the ContentV iew behind the |
876 // infobars. http://crbug.com/430701 | 930 // infobars. http://crbug.com/430701 |
877 return true; | 931 return true; |
878 } | 932 } |
879 } | 933 } |
OLD | NEW |