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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBar.java

Issue 1170843002: [Andorid] Migrate to ClipDrawable progress bar. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: testing timeout correction Created 5 years, 5 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.widget; 5 package org.chromium.chrome.browser.widget;
6 6
7 import android.animation.Animator; 7 import android.animation.TimeAnimator;
8 import android.animation.AnimatorListenerAdapter; 8 import android.animation.TimeAnimator.TimeListener;
9 import android.animation.ObjectAnimator;
10 import android.content.Context; 9 import android.content.Context;
11 import android.graphics.drawable.Drawable;
12 import android.graphics.drawable.LayerDrawable;
13 import android.util.AttributeSet; 10 import android.util.AttributeSet;
14 import android.view.View;
15 11
16 import org.chromium.base.VisibleForTesting; 12 import org.chromium.base.VisibleForTesting;
17 import org.chromium.ui.interpolators.BakedBezierInterpolator; 13 import org.chromium.chrome.browser.util.MathUtils;
18 14
19 /** 15 /**
20 * Progress bar for use in the Toolbar view. 16 * Progress bar for use in the Toolbar view.
21 */ 17 */
22 public class ToolbarProgressBar extends SmoothProgressBar { 18 public class ToolbarProgressBar extends ClipDrawableProgressBar {
23 private static final long PROGRESS_CLEARING_DELAY_MS = 200; 19 private static final float ALPHA_CHANGE_SPEED_PER_SECOND = 8.0f;
24 private static final int SHOW_HIDE_DURATION_MS = 100; 20 private static final long HIDING_DELAY_MS = 100;
25 21
26 private final Runnable mClearLoadProgressRunnable; 22 // Public duration constants are for testing.
27 private int mDesiredVisibility; 23 public static final long SHOWING_DURATION_MS =
28 private Animator mShowAnimator; 24 (long) Math.ceil(1.0f / ALPHA_CHANGE_SPEED_PER_SECOND * 1000);
29 private Animator mHideAnimator; 25 public static final long HIDING_DURATION_MS = HIDING_DELAY_MS
26 + (long) Math.ceil(1.0f / ALPHA_CHANGE_SPEED_PER_SECOND * 1000);
27
28 private boolean mIsStarted;
29 private float mTargetAlpha;
30 private boolean mIsHideRunnablePosted;
31 private TimeAnimator mAlphaAnimator = new TimeAnimator();
32 private final Runnable mHideRunnable = new Runnable() {
33 @Override
34 public void run() {
35 animateAlphaTo(0.0f);
36 mIsHideRunnablePosted = false;
37 }
38 };
30 39
31 /** 40 /**
32 * Creates a toolbar progress bar. 41 * Creates a toolbar progress bar.
42 *
33 * @param context the application environment. 43 * @param context the application environment.
34 * @param attrs the xml attributes that should be used to initialize this vi ew. 44 * @param attrs the xml attributes that should be used to initialize this vi ew.
35 */ 45 */
36 public ToolbarProgressBar(Context context, AttributeSet attrs) { 46 public ToolbarProgressBar(Context context, AttributeSet attrs) {
37 super(context, attrs); 47 super(context, attrs);
38 // The base constructor will trigger a progress change and alter the exp ected
39 // visibility, so force a visibility change to reset the state.
40 setVisibility(VISIBLE);
41 48
42 mClearLoadProgressRunnable = new Runnable() { 49 setAlpha(mTargetAlpha);
50
51 mAlphaAnimator.setTimeListener(new TimeListener() {
Ted C 2015/07/15 02:41:12 What is the benefit of the alpha animator? Doesn'
Kibeom Kim (inactive) 2015/07/15 11:22:46 I like TimeAnimator in general, I don't know why I
43 @Override 52 @Override
44 public void run() { 53 public void onTimeUpdate(TimeAnimator animation, long totalTimeMs, l ong deltaTimeMs) {
45 setProgress(0); 54 float alpha = getAlpha();
46 }
47 };
48 55
49 // Hide the background portion of the system progress bar. 56 if (alpha == mTargetAlpha) {
50 Drawable progressDrawable = getProgressDrawable(); 57 mAlphaAnimator.end();
51 if (progressDrawable instanceof LayerDrawable) { 58 return;
52 Drawable progressBackgroundDrawable = 59 }
53 ((LayerDrawable) progressDrawable)
54 .findDrawableByLayerId(android.R.id.background);
55 if (progressBackgroundDrawable != null) {
56 progressBackgroundDrawable.setVisible(false, false);
57 progressBackgroundDrawable.setAlpha(0);
58 }
59 }
60 }
61 60
62 @Override 61 float maxAlphaChange = ALPHA_CHANGE_SPEED_PER_SECOND * deltaTime Ms / 1000.0f;
63 public void setSecondaryProgress(int secondaryProgress) { 62 setAlpha(alpha
64 super.setSecondaryProgress(secondaryProgress); 63 + MathUtils.clamp(mTargetAlpha - alpha, -maxAlphaChange, maxAlphaChange));
65 setVisibilityForProgress();
66 }
67
68 @Override
69 protected void setProgressInternal(int progress) {
70 super.setProgressInternal(progress);
71
72 if (progress == getMax()) {
73 postDelayed(mClearLoadProgressRunnable, PROGRESS_CLEARING_DELAY_MS);
74 }
75
76 setVisibilityForProgress();
77 }
78
79 @Override
80 public void setVisibility(int v) {
81 mDesiredVisibility = v;
82 setVisibilityForProgress();
83 }
84
85 private void setVisibilityForProgress() {
86 if (mDesiredVisibility != VISIBLE) {
87 super.setVisibility(mDesiredVisibility);
88 return;
89 }
90
91 int progress = Math.max(getProgress(), getSecondaryProgress());
92 super.setVisibility(progress == 0 ? INVISIBLE : VISIBLE);
93 }
94
95 @Override
96 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
97 super.onSizeChanged(w, h, oldw, oldh);
98
99 // Some versions of Android have a bug where they don't properly update the drawables with
100 // the correct bounds. setProgressDrawable has been overridden to prope rly push the bounds
101 // but on rotation they weren't always being set. Forcing a bounds upda te on size changes
102 // fixes the problem.
103 setProgressDrawable(getProgressDrawable());
104 }
105
106 @Override
107 protected void onLayout(boolean changed, int left, int top, int right, int b ottom) {
108 super.onLayout(changed, left, top, right, bottom);
109 buildAnimators();
110 setPivotY(getHeight());
111 }
112
113 @Override
114 public void setProgressDrawable(Drawable d) {
115 Drawable currentDrawable = getProgressDrawable();
116
117 super.setProgressDrawable(d);
118
119 if (currentDrawable != null && d instanceof LayerDrawable) {
120 LayerDrawable ld = (LayerDrawable) d;
121 for (int i = 0; i < ld.getNumberOfLayers(); i++) {
122 ld.getDrawable(i).setBounds(currentDrawable.getBounds());
123 }
124 }
125 }
126
127 /**
128 * @return Whether or not this progress bar has animations running for showi ng/hiding itself.
129 */
130 @VisibleForTesting
131 boolean isAnimatingForShowOrHide() {
132 return (mShowAnimator != null && mShowAnimator.isStarted())
133 || (mHideAnimator != null && mHideAnimator.isStarted());
134 }
135
136 private void buildAnimators() {
137 if (mShowAnimator != null && mShowAnimator.isRunning()) mShowAnimator.en d();
138 if (mHideAnimator != null && mHideAnimator.isRunning()) mHideAnimator.en d();
139
140 mShowAnimator = ObjectAnimator.ofFloat(this, View.SCALE_Y, 0.f, 1.f);
141 mShowAnimator.setDuration(SHOW_HIDE_DURATION_MS);
142 mShowAnimator.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE);
143 mShowAnimator.addListener(new AnimatorListenerAdapter() {
144 @Override
145 public void onAnimationStart(Animator animation) {
146 setSecondaryProgress(getMax());
147 }
148 });
149
150 mHideAnimator = ObjectAnimator.ofFloat(this, View.SCALE_Y, 1.f, 0.f);
151 mHideAnimator.setDuration(SHOW_HIDE_DURATION_MS);
152 mHideAnimator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
153 mHideAnimator.addListener(new AnimatorListenerAdapter() {
154 @Override
155 public void onAnimationEnd(Animator animation) {
156 setSecondaryProgress(0);
157 } 64 }
158 }); 65 });
159 } 66 }
160 67
68 /**
69 * Start showing progress bar animation.
70 */
71 public void start() {
72 mIsStarted = true;
73
74 removeCallbacks(mHideRunnable);
75 mIsHideRunnablePosted = false;
76
77 animateAlphaTo(1.0f);
78 }
79
80 /**
81 * Start hiding progress bar animation.
82 */
83 public void finish() {
84 mIsStarted = false;
Ted C 2015/07/15 02:41:12 Is page load finished always going to happen right
Kibeom Kim (inactive) 2015/07/15 11:22:46 I think, regardless of happening right after 100%
Ted C 2015/07/15 17:42:59 Not sure I agree with the "correctness" assertion.
Kibeom Kim (inactive) 2015/07/16 04:45:48 Investigation so far: In general, progress can be
85
86 removeCallbacks(mHideRunnable);
87 postDelayed(mHideRunnable, HIDING_DELAY_MS);
88 mIsHideRunnablePosted = true;
89 }
90
91 /**
92 * @return Whether or not this progress bar has animations running or schedu led for
93 * showing/hiding itself.
94 */
95 @VisibleForTesting
96 public boolean isAnimatingForShowOrHide() {
97 return mAlphaAnimator.isStarted() || mIsHideRunnablePosted;
98 }
99
100 private void animateAlphaTo(float targetAlpha) {
101 mTargetAlpha = targetAlpha;
102 if (getAlpha() != targetAlpha) mAlphaAnimator.start();
103 }
104
105 // ClipDrawableProgressBar implementation.
106
161 @Override 107 @Override
162 public void setProgress(int progress) { 108 public void setProgress(float progress) {
163 // If the show animator has started, the progress bar needs to be tracke d as if it is 109 assert mIsStarted;
164 // currently showing. This makes sure we trigger the proper hide animat ion and cancel the
165 // show animation if we show/hide the bar very fast. See crbug.com/4533 60.
166 boolean isShowing =
167 getProgress() > 0 || (mShowAnimator != null && mShowAnimator.isS tarted());
168 boolean willShow = progress > 0;
169
170 removeCallbacks(mClearLoadProgressRunnable);
171 super.setProgress(progress); 110 super.setProgress(progress);
172
173 if (isShowing != willShow) {
174 if (mShowAnimator == null || mHideAnimator == null) buildAnimators() ;
175
176 if (mShowAnimator.isRunning()) mShowAnimator.end();
177 if (mHideAnimator.isRunning()) mHideAnimator.end();
178
179 if (willShow) {
180 mShowAnimator.start();
181 } else {
182 mHideAnimator.start();
183 }
184 }
185 } 111 }
186 } 112 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698