| Index: chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBarAnimatingView.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBarAnimatingView.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBarAnimatingView.java
|
| index 71a01accf8fce0496cb91b3fcd316080619cebfb..ca48561a49a67a9c0f8fce78e2dad1ba7a475f4d 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBarAnimatingView.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ToolbarProgressBarAnimatingView.java
|
| @@ -5,6 +5,7 @@
|
| package org.chromium.chrome.browser.widget;
|
|
|
| import android.animation.Animator;
|
| +import android.animation.Animator.AnimatorListener;
|
| import android.animation.AnimatorListenerAdapter;
|
| import android.animation.AnimatorSet;
|
| import android.animation.ValueAnimator;
|
| @@ -27,20 +28,35 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| /** The drawable inside this ImageView. */
|
| private final ColorDrawable mAnimationDrawable;
|
|
|
| - /** The amount of time the fast part of the animation should take in ms. */
|
| - private static final int FAST_ANIMATION_DURATION_MS = 900;
|
| + /** The fraction of the total time that the slow animation should take. */
|
| + private static final float SLOW_ANIMATION_FRACTION = 0.60f;
|
|
|
| - /** The amount of time the slow part of the animation should take in ms. */
|
| - private static final int SLOW_ANIMATION_DURATION_MS = 1600;
|
| + /** The fraction of the total time that the fast animation delay should take. */
|
| + private static final float FAST_ANIMATION_DELAY = 0.02f;
|
| +
|
| + /** The fraction of the total time that the fast animation should take. */
|
| + private static final float FAST_ANIMATION_FRACTION = 0.38f;
|
|
|
| /** The time between animation sequences. */
|
| private static final int ANIMATION_DELAY_MS = 1000;
|
|
|
| /** The width of the animating bar relative to the current width of the progress bar. */
|
| - private static final float ANIMATING_BAR_SCALE = 0.5f;
|
| + private static final float ANIMATING_BAR_SCALE = 0.3f;
|
| +
|
| + /**
|
| + * The width of the animating bar relative to the current width of the progress bar for the
|
| + * first half of the slow animation.
|
| + */
|
| + private static final float SMALL_ANIMATING_BAR_SCALE = 0.1f;
|
| +
|
| + /** The fraction of overall completion that the small animating bar should be expanded at. */
|
| + private static final float SMALL_BAR_EXPANSION_COMPLETE = 0.6f;
|
| +
|
| + /** The maximum size of the animating view. */
|
| + private static final float ANIMATING_VIEW_MAX_WIDTH_DP = 400;
|
|
|
| /** Interpolator for enter and exit animation. */
|
| - private final BakedBezierInterpolator mBezier = BakedBezierInterpolator.TRANSFORM_CURVE;
|
| + private final BakedBezierInterpolator mBezier = BakedBezierInterpolator.FADE_OUT_CURVE;
|
|
|
| /** The current width of the progress bar. */
|
| private float mProgressWidth = 0;
|
| @@ -48,6 +64,12 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| /** The set of individual animators that constitute the whole animation sequence. */
|
| private final AnimatorSet mAnimatorSet;
|
|
|
| + /** The animator controlling the fast animation. */
|
| + private final ValueAnimator mFastAnimation;
|
| +
|
| + /** The animator controlling the slow animation. */
|
| + private final ValueAnimator mSlowAnimation;
|
| +
|
| /** Track if the animation has been canceled. */
|
| private boolean mIsCanceled;
|
|
|
| @@ -60,11 +82,11 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| /** The last fraction of the animation that was drawn. */
|
| private float mLastAnimatedFraction;
|
|
|
| - /**
|
| - * If the animation is currently running. This is needed because Animator.isStarted() is not
|
| - * reliable on JellyBean.
|
| - */
|
| - private boolean mIsAnimationRunning;
|
| + /** The last animation that received an update. */
|
| + private ValueAnimator mLastUpdatedAnimation;
|
| +
|
| + /** The ratio of px to dp. */
|
| + private float mDpToPx;
|
|
|
| /**
|
| * An animation update listener that moves an ImageView across the progress bar.
|
| @@ -72,8 +94,9 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| private class ProgressBarUpdateListener implements AnimatorUpdateListener {
|
| @Override
|
| public void onAnimationUpdate(ValueAnimator animation) {
|
| + mLastUpdatedAnimation = animation;
|
| mLastAnimatedFraction = animation.getAnimatedFraction();
|
| - updateAnimation(mLastAnimatedFraction);
|
| + updateAnimation(mLastUpdatedAnimation, mLastAnimatedFraction);
|
| }
|
| }
|
|
|
| @@ -85,6 +108,7 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| super(context);
|
| setLayoutParams(layoutParams);
|
| mIsRtl = LocalizationUtils.isLayoutRtl();
|
| + mDpToPx = getResources().getDisplayMetrics().density;
|
|
|
| mAnimationDrawable = new ColorDrawable(Color.WHITE);
|
|
|
| @@ -93,28 +117,44 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| mListener = new ProgressBarUpdateListener();
|
| mAnimatorSet = new AnimatorSet();
|
|
|
| - ValueAnimator fastAnimation = new ValueAnimator();
|
| - fastAnimation.setFloatValues(0.0f, 1.0f);
|
| - fastAnimation.setDuration(FAST_ANIMATION_DURATION_MS);
|
| - fastAnimation.addUpdateListener(mListener);
|
| + mSlowAnimation = new ValueAnimator();
|
| + mSlowAnimation.setFloatValues(0.0f, 1.0f);
|
| + mSlowAnimation.addUpdateListener(mListener);
|
| +
|
| + mFastAnimation = new ValueAnimator();
|
| + mFastAnimation.setFloatValues(0.0f, 1.0f);
|
| + mFastAnimation.addUpdateListener(mListener);
|
|
|
| - ValueAnimator slowAnimation = new ValueAnimator();
|
| - slowAnimation.setFloatValues(0.0f, 1.0f);
|
| - slowAnimation.setDuration(SLOW_ANIMATION_DURATION_MS);
|
| - slowAnimation.addUpdateListener(mListener);
|
| + updateAnimationDuration();
|
|
|
| - mAnimatorSet.playSequentially(fastAnimation, slowAnimation);
|
| + mAnimatorSet.playSequentially(mSlowAnimation, mFastAnimation);
|
|
|
| - slowAnimation.addListener(new AnimatorListenerAdapter() {
|
| + AnimatorListener listener = new AnimatorListenerAdapter() {
|
| @Override
|
| public void onAnimationEnd(Animator a) {
|
| // Replay the animation if it has not been canceled.
|
| if (mIsCanceled) return;
|
| // Repeats of the animation should have a start delay.
|
| mAnimatorSet.setStartDelay(ANIMATION_DELAY_MS);
|
| - mAnimatorSet.start();
|
| + updateAnimationDuration();
|
| + // Only restart the animation if the last animation is ending.
|
| + if (a == mFastAnimation) mAnimatorSet.start();
|
| }
|
| - });
|
| + };
|
| +
|
| + mSlowAnimation.addListener(listener);
|
| + mFastAnimation.addListener(listener);
|
| + }
|
| +
|
| + /**
|
| + * Update the duration of the animation based on the width of the progress bar.
|
| + */
|
| + private void updateAnimationDuration() {
|
| + // Total duration: logE(progress_dp) * 200 * 1.3
|
| + long totalDuration = (long) (Math.log(mProgressWidth / mDpToPx) / Math.log(Math.E)) * 260;
|
| + mSlowAnimation.setDuration((long) (totalDuration * SLOW_ANIMATION_FRACTION));
|
| + mFastAnimation.setStartDelay((long) (totalDuration * FAST_ANIMATION_DELAY));
|
| + mFastAnimation.setDuration((long) (totalDuration * FAST_ANIMATION_FRACTION));
|
| }
|
|
|
| /**
|
| @@ -122,8 +162,8 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| */
|
| public void startAnimation() {
|
| mIsCanceled = false;
|
| - if (!mIsAnimationRunning) {
|
| - mIsAnimationRunning = true;
|
| + if (!mAnimatorSet.isStarted()) {
|
| + updateAnimationDuration();
|
| // Set the initial start delay to 0ms so it starts immediately.
|
| mAnimatorSet.setStartDelay(0);
|
|
|
| @@ -141,18 +181,36 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
|
|
| /**
|
| * Update the animating view.
|
| + * @param animator The current running animator.
|
| * @param animatedFraction The current fraction of completion for the animation.
|
| */
|
| - private void updateAnimation(float animatedFraction) {
|
| + private void updateAnimation(ValueAnimator animator, float animatedFraction) {
|
| + if (mIsCanceled) return;
|
| float bezierProgress = mBezier.getInterpolation(animatedFraction);
|
|
|
| // Left and right bound change based on if the layout is RTL.
|
| float leftBound = mIsRtl ? -mProgressWidth : 0.0f;
|
| float rightBound = mIsRtl ? 0.0f : mProgressWidth;
|
|
|
| + float barScale = ANIMATING_BAR_SCALE;
|
| +
|
| + // If the current animation is the slow animation, the bar slowly expands from 20% of the
|
| + // progress bar width to 30%.
|
| + if (animator == mSlowAnimation && animatedFraction <= SMALL_BAR_EXPANSION_COMPLETE) {
|
| + float sizeDiff = ANIMATING_BAR_SCALE - SMALL_ANIMATING_BAR_SCALE;
|
| +
|
| + // Since the bar will only expand for the first 60% of the animation, multiply the
|
| + // animated fraction by 1/0.6 to get the fraction completed.
|
| + float completeFraction = (animatedFraction / SMALL_BAR_EXPANSION_COMPLETE);
|
| +
|
| + barScale = SMALL_ANIMATING_BAR_SCALE + sizeDiff * completeFraction;
|
| + }
|
| +
|
| // Include the width of the animating bar in this computation so it comes from
|
| // off-screen.
|
| - float animatingWidth = mProgressWidth * ANIMATING_BAR_SCALE;
|
| + float animatingWidth = Math.min(ANIMATING_VIEW_MAX_WIDTH_DP * mDpToPx,
|
| + mProgressWidth * barScale);
|
| +
|
| float animatorCenter =
|
| ((mProgressWidth + animatingWidth) * bezierProgress) - animatingWidth / 2.0f;
|
| if (mIsRtl) animatorCenter *= -1.0f;
|
| @@ -186,7 +244,6 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| */
|
| public void cancelAnimation() {
|
| mIsCanceled = true;
|
| - mIsAnimationRunning = false;
|
| // Reset position and alpha.
|
| setScaleX(0.0f);
|
| setTranslationX(0.0f);
|
| @@ -200,8 +257,11 @@ public class ToolbarProgressBarAnimatingView extends ImageView {
|
| * @param progressWidth The width of the contaiing progress bar.
|
| */
|
| public void update(float progressWidth) {
|
| + // Since the progress bar can become visible before current progress is sent, the width
|
| + // needs to be updated even if the progess bar isn't showing. The result of not having
|
| + // this is most noticable if you rotate the device on a slow page.
|
| mProgressWidth = progressWidth;
|
| - updateAnimation(mLastAnimatedFraction);
|
| + updateAnimation(mLastUpdatedAnimation, mLastAnimatedFraction);
|
| }
|
|
|
| /**
|
|
|