Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java

Issue 2846663002: Peek new infobars behind existing ones (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698