summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorjdduke <jdduke@chromium.org>2015-05-06 10:59:56 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-06 18:00:32 +0000
commitafabd785dac54a2325206427ed5140ec7f7caf5a (patch)
tree49c5c37a885e4b1a732a8e7e13a43f2b7bcd2789 /third_party
parent9044bfa1dfb376789618573cd6ab2bd9996c318d (diff)
downloadchromium_src-afabd785dac54a2325206427ed5140ec7f7caf5a.zip
chromium_src-afabd785dac54a2325206427ed5140ec7f7caf5a.tar.gz
chromium_src-afabd785dac54a2325206427ed5140ec7f7caf5a.tar.bz2
[Android] Cherry-pick upstream appcompat fixes for SwipeRefreshLayout
Cherry-pick several recent changes to SwipeRefreshLayout and its dependencies. This includes both several stylistic tweaks as well as a fix for animation transitions on several devices. BUG=485145 Review URL: https://codereview.chromium.org/1127193002 Cr-Commit-Position: refs/heads/master@{#328559}
Diffstat (limited to 'third_party')
-rw-r--r--third_party/android_swipe_refresh/BUILD.gn3
-rw-r--r--third_party/android_swipe_refresh/README.chromium2
-rw-r--r--third_party/android_swipe_refresh/android_swipe_refresh.gyp3
-rw-r--r--third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/CircleImageView.java14
-rw-r--r--third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/MaterialProgressDrawable.java257
-rw-r--r--third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java26
6 files changed, 202 insertions, 103 deletions
diff --git a/third_party/android_swipe_refresh/BUILD.gn b/third_party/android_swipe_refresh/BUILD.gn
index ad14d81..c7939b0 100644
--- a/third_party/android_swipe_refresh/BUILD.gn
+++ b/third_party/android_swipe_refresh/BUILD.gn
@@ -8,4 +8,7 @@ assert(is_android)
android_library("android_swipe_refresh_java") {
DEPRECATED_java_in_dir = "java/src"
+ deps = [
+ "//third_party/android_tools:android_support_v13_java",
+ ]
}
diff --git a/third_party/android_swipe_refresh/README.chromium b/third_party/android_swipe_refresh/README.chromium
index 9cdec7c..3fde9b2 100644
--- a/third_party/android_swipe_refresh/README.chromium
+++ b/third_party/android_swipe_refresh/README.chromium
@@ -12,7 +12,7 @@ pull-to-refresh styled layout for touch-activated refresh of view contents.
Local Modifications:
CircleImageView, MaterialProgressDrawable
- * The package has been changed, and all ViewCompat dependencies removed.
+ * The package has been changed, and most ViewCompat dependencies removed.
SwipeRefreshLayout
* MotionEvent-behavior has been changed to allow more abstract inputs.
diff --git a/third_party/android_swipe_refresh/android_swipe_refresh.gyp b/third_party/android_swipe_refresh/android_swipe_refresh.gyp
index 52e409b..c7f7e0f 100644
--- a/third_party/android_swipe_refresh/android_swipe_refresh.gyp
+++ b/third_party/android_swipe_refresh/android_swipe_refresh.gyp
@@ -7,6 +7,9 @@
{
'target_name': 'android_swipe_refresh_java',
'type': 'none',
+ 'dependencies': [
+ '../android_tools/android_tools.gyp:android_support_v13_javalib',
+ ],
'variables': {
'java_in_dir': 'java',
},
diff --git a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/CircleImageView.java b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/CircleImageView.java
index fcb2185..c5611fe 100644
--- a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/CircleImageView.java
+++ b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/CircleImageView.java
@@ -85,7 +85,7 @@ class CircleImageView extends ImageView {
setLayerType(View.LAYER_TYPE_SOFTWARE, circle.getPaint());
circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
KEY_SHADOW_COLOR);
- final int padding = (int) mShadowRadius;
+ final int padding = mShadowRadius;
// set padding so the inner image sits correctly within the shadow.
setPadding(padding, padding, padding, padding);
return circle;
@@ -126,11 +126,17 @@ class CircleImageView extends ImageView {
/**
* Update the background color of the circle image view.
+ *
+ * @param colorRes Id of a color resource.
*/
- public void setBackgroundColor(int colorRes) {
+ public void setBackgroundColorRes(int colorRes) {
+ setBackgroundColor(getContext().getResources().getColor(colorRes));
+ }
+
+ @Override
+ public void setBackgroundColor(int color) {
if (getBackground() instanceof ShapeDrawable) {
- final Resources res = getResources();
- ((ShapeDrawable) getBackground()).getPaint().setColor(res.getColor(colorRes));
+ ((ShapeDrawable) getBackground()).getPaint().setColor(color);
}
}
diff --git a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/MaterialProgressDrawable.java b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/MaterialProgressDrawable.java
index 23a6a37..87df79a 100644
--- a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/MaterialProgressDrawable.java
+++ b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/MaterialProgressDrawable.java
@@ -26,7 +26,6 @@ import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
-import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
@@ -35,6 +34,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Animatable;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.DisplayMetrics;
import android.view.View;
@@ -45,14 +45,13 @@ import java.util.ArrayList;
/**
* Fancy progress indicator for Material theme.
*
- * @hide
+ * @hide
*/
class MaterialProgressDrawable extends Drawable implements Animatable {
private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
- private static final Interpolator END_CURVE_INTERPOLATOR = new EndCurveInterpolator();
- private static final Interpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator();
- private static final Interpolator EASE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
+ private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
+ private static final float FULL_ROTATION = 1080.0f;
@Retention(RetentionPolicy.CLASS)
public @interface ProgressDrawableSize {}
// Maps to ProgressBar.Large style
@@ -74,8 +73,16 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
Color.BLACK
};
+ /**
+ * The value in the linear interpolator for animating the drawable at which
+ * the color transition should start
+ */
+ private static final float COLOR_START_DELAY_OFFSET = 0.75f;
+ private static final float END_TRIM_START_DELAY_OFFSET = 0.5f;
+ private static final float START_TRIM_DURATION_OFFSET = 0.5f;
+
/** The duration of a single progress spin in milliseconds. */
- private static final int ANIMATION_DURATION = 1000 * 80 / 60;
+ private static final int ANIMATION_DURATION = 1332;
/** The number of points in the progress "star". */
private static final float NUM_POINTS = 5f;
@@ -104,7 +111,7 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
private float mRotationCount;
private double mWidth;
private double mHeight;
- private Animation mFinishAnimation;
+ private boolean mFinishing;
public MaterialProgressDrawable(Context context, View parent) {
mParent = parent;
@@ -282,10 +289,13 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
mRing.storeOriginals();
// Already showing some part of the ring
if (mRing.getEndTrim() != mRing.getStartTrim()) {
- mParent.startAnimation(mFinishAnimation);
+ mFinishing = true;
+ mAnimation.setDuration(ANIMATION_DURATION/2);
+ mParent.startAnimation(mAnimation);
} else {
mRing.setColorIndex(0);
mRing.resetOriginals();
+ mAnimation.setDuration(ANIMATION_DURATION);
mParent.startAnimation(mAnimation);
}
}
@@ -299,78 +309,122 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
mRing.resetOriginals();
}
- private void setupAnimators() {
- final Ring ring = mRing;
- final Animation finishRingAnimation = new Animation() {
- public void applyTransformation(float interpolatedTime, Transformation t) {
- // shrink back down and complete a full rotation before starting other circles
- // Rotation goes between [0..1].
- float targetRotation = (float) (Math.floor(ring.getStartingRotation()
- / MAX_PROGRESS_ARC) + 1f);
- final float startTrim = ring.getStartingStartTrim()
- + (ring.getStartingEndTrim() - ring.getStartingStartTrim())
- * interpolatedTime;
- ring.setStartTrim(startTrim);
- final float rotation = ring.getStartingRotation()
- + ((targetRotation - ring.getStartingRotation()) * interpolatedTime);
- ring.setRotation(rotation);
- ring.setArrowScale(1 - interpolatedTime);
- }
- };
- finishRingAnimation.setInterpolator(EASE_INTERPOLATOR);
- finishRingAnimation.setDuration(ANIMATION_DURATION/2);
- finishRingAnimation.setAnimationListener(new Animation.AnimationListener() {
+ private float getMinProgressArc(Ring ring) {
+ return (float) Math.toRadians(
+ ring.getStrokeWidth() / (2 * Math.PI * ring.getCenterRadius()));
+ }
- @Override
- public void onAnimationStart(Animation animation) {
- }
+ // Adapted from ArgbEvaluator.java
+ private int evaluateColorChange(float fraction, int startValue, int endValue) {
+ int startInt = (Integer) startValue;
+ int startA = (startInt >> 24) & 0xff;
+ int startR = (startInt >> 16) & 0xff;
+ int startG = (startInt >> 8) & 0xff;
+ int startB = startInt & 0xff;
+
+ int endInt = (Integer) endValue;
+ int endA = (endInt >> 24) & 0xff;
+ int endR = (endInt >> 16) & 0xff;
+ int endG = (endInt >> 8) & 0xff;
+ int endB = endInt & 0xff;
+
+ return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
+ (int)((startR + (int)(fraction * (endR - startR))) << 16) |
+ (int)((startG + (int)(fraction * (endG - startG))) << 8) |
+ (int)((startB + (int)(fraction * (endB - startB))));
+ }
- @Override
- public void onAnimationEnd(Animation animation) {
- ring.goToNextColor();
- ring.storeOriginals();
- ring.setShowArrow(false);
- mParent.startAnimation(mAnimation);
- }
+ /**
+ * Update the ring color if this is within the last 25% of the animation.
+ * The new ring color will be a translation from the starting ring color to
+ * the next color.
+ */
+ private void updateRingColor(float interpolatedTime, Ring ring) {
+ if (interpolatedTime > COLOR_START_DELAY_OFFSET) {
+ // scale the interpolatedTime so that the full
+ // transformation from 0 - 1 takes place in the
+ // remaining time
+ ring.setColor(evaluateColorChange((interpolatedTime - COLOR_START_DELAY_OFFSET)
+ / (1.0f - COLOR_START_DELAY_OFFSET), ring.getStartingColor(),
+ ring.getNextColor()));
+ }
+ }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- });
+ private void applyFinishTranslation(float interpolatedTime, Ring ring) {
+ // shrink back down and complete a full rotation before
+ // starting other circles
+ // Rotation goes between [0..1].
+ updateRingColor(interpolatedTime, ring);
+ float targetRotation = (float) (Math.floor(ring.getStartingRotation() / MAX_PROGRESS_ARC)
+ + 1f);
+ final float minProgressArc = getMinProgressArc(ring);
+ final float startTrim = ring.getStartingStartTrim()
+ + (ring.getStartingEndTrim() - minProgressArc - ring.getStartingStartTrim())
+ * interpolatedTime;
+ ring.setStartTrim(startTrim);
+ ring.setEndTrim(ring.getStartingEndTrim());
+ final float rotation = ring.getStartingRotation()
+ + ((targetRotation - ring.getStartingRotation()) * interpolatedTime);
+ ring.setRotation(rotation);
+ }
+
+ private void setupAnimators() {
+ final Ring ring = mRing;
final Animation animation = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
- // The minProgressArc is calculated from 0 to create an angle that
- // matches the stroke width.
- final float minProgressArc = (float) Math.toRadians(ring.getStrokeWidth()
- / (2 * Math.PI * ring.getCenterRadius()));
- final float startingEndTrim = ring.getStartingEndTrim();
- final float startingTrim = ring.getStartingStartTrim();
- final float startingRotation = ring.getStartingRotation();
-
- // Offset the minProgressArc to where the endTrim is located.
- final float minArc = MAX_PROGRESS_ARC - minProgressArc;
- final float endTrim = startingEndTrim
- + (minArc * START_CURVE_INTERPOLATOR.getInterpolation(interpolatedTime));
- ring.setEndTrim(endTrim);
-
- final float startTrim = startingTrim
- + (MAX_PROGRESS_ARC * END_CURVE_INTERPOLATOR
- .getInterpolation(interpolatedTime));
- ring.setStartTrim(startTrim);
-
- final float rotation = startingRotation + (0.25f * interpolatedTime);
- ring.setRotation(rotation);
-
- float groupRotation = ((720.0f / NUM_POINTS) * interpolatedTime)
- + (720.0f * (mRotationCount / NUM_POINTS));
- setRotation(groupRotation);
+ if (mFinishing) {
+ applyFinishTranslation(interpolatedTime, ring);
+ } else {
+ // The minProgressArc is calculated from 0 to create an
+ // angle that matches the stroke width.
+ final float minProgressArc = getMinProgressArc(ring);
+ final float startingEndTrim = ring.getStartingEndTrim();
+ final float startingTrim = ring.getStartingStartTrim();
+ final float startingRotation = ring.getStartingRotation();
+
+ updateRingColor(interpolatedTime, ring);
+
+ // Moving the start trim only occurs in the first 50% of a
+ // single ring animation
+ if (interpolatedTime <= START_TRIM_DURATION_OFFSET) {
+ // scale the interpolatedTime so that the full
+ // transformation from 0 - 1 takes place in the
+ // remaining time
+ final float scaledTime = (interpolatedTime)
+ / (1.0f - START_TRIM_DURATION_OFFSET);
+ final float startTrim = startingTrim
+ + ((MAX_PROGRESS_ARC - minProgressArc) * MATERIAL_INTERPOLATOR
+ .getInterpolation(scaledTime));
+ ring.setStartTrim(startTrim);
+ }
+
+ // Moving the end trim starts after 50% of a single ring
+ // animation completes
+ if (interpolatedTime > END_TRIM_START_DELAY_OFFSET) {
+ // scale the interpolatedTime so that the full
+ // transformation from 0 - 1 takes place in the
+ // remaining time
+ final float minArc = MAX_PROGRESS_ARC - minProgressArc;
+ float scaledTime = (interpolatedTime - START_TRIM_DURATION_OFFSET)
+ / (1.0f - START_TRIM_DURATION_OFFSET);
+ final float endTrim = startingEndTrim
+ + (minArc * MATERIAL_INTERPOLATOR.getInterpolation(scaledTime));
+ ring.setEndTrim(endTrim);
+ }
+
+ final float rotation = startingRotation + (0.25f * interpolatedTime);
+ ring.setRotation(rotation);
+
+ float groupRotation = ((FULL_ROTATION / NUM_POINTS) * interpolatedTime)
+ + (FULL_ROTATION * (mRotationCount / NUM_POINTS));
+ setRotation(groupRotation);
+ }
}
};
animation.setRepeatCount(10);
animation.setRepeatMode(Animation.RESTART);
animation.setInterpolator(LINEAR_INTERPOLATOR);
- animation.setDuration(ANIMATION_DURATION);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
@@ -388,10 +442,17 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
ring.storeOriginals();
ring.goToNextColor();
ring.setStartTrim(ring.getEndTrim());
- mRotationCount = (mRotationCount + 1) % (NUM_POINTS);
+ if (mFinishing) {
+ // finished closing the last ring from the swipe gesture; go
+ // into progress mode
+ mFinishing = false;
+ animation.setDuration(ANIMATION_DURATION);
+ ring.setShowArrow(false);
+ } else {
+ mRotationCount = (mRotationCount + 1) % (NUM_POINTS);
+ }
}
});
- mFinishAnimation = finishRingAnimation;
mAnimation = animation;
}
@@ -442,6 +503,7 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
private int mAlpha;
private final Paint mCirclePaint = new Paint();
private int mBackgroundColor;
+ private int mCurrentColor;
public Ring(Callback callback) {
mCallback = callback;
@@ -481,7 +543,7 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
final float endAngle = (mEndTrim + mRotation) * 360;
float sweepAngle = endAngle - startAngle;
- mPaint.setColor(mColors[mColorIndex]);
+ mPaint.setColor(mCurrentColor);
c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
drawTriangle(c, startAngle, sweepAngle, bounds);
@@ -519,7 +581,7 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
- mArrowPaint.setColor(mColors[mColorIndex]);
+ mArrowPaint.setColor(mCurrentColor);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
@@ -538,11 +600,34 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
}
/**
+ * Set the absolute color of the progress spinner. This is should only
+ * be used when animating between current and next color when the
+ * spinner is rotating.
+ *
+ * @param color int describing the color.
+ */
+ public void setColor(int color) {
+ mCurrentColor = color;
+ }
+
+ /**
* @param index Index into the color array of the color to display in
* the progress spinner.
*/
public void setColorIndex(int index) {
mColorIndex = index;
+ mCurrentColor = mColors[mColorIndex];
+ }
+
+ /**
+ * @return int describing the next color the progress spinner should use when drawing.
+ */
+ public int getNextColor() {
+ return mColors[getNextColorIndex()];
+ }
+
+ private int getNextColorIndex() {
+ return (mColorIndex + 1) % (mColors.length);
}
/**
@@ -550,7 +635,7 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
* wrap back to the beginning of colors.
*/
public void goToNextColor() {
- mColorIndex = (mColorIndex + 1) % (mColors.length);
+ setColorIndex(getNextColorIndex());
}
public void setColorFilter(ColorFilter filter) {
@@ -608,6 +693,10 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
return mStartingEndTrim;
}
+ public int getStartingColor() {
+ return mColors[mColorIndex];
+ }
+
@SuppressWarnings("unused")
public void setEndTrim(float endTrim) {
mEndTrim = endTrim;
@@ -711,24 +800,4 @@ class MaterialProgressDrawable extends Drawable implements Animatable {
mCallback.invalidateDrawable(null);
}
}
-
- /**
- * Squishes the interpolation curve into the second half of the animation.
- */
- private static class EndCurveInterpolator extends AccelerateDecelerateInterpolator {
- @Override
- public float getInterpolation(float input) {
- return super.getInterpolation(Math.max(0, (input - 0.5f) * 2.0f));
- }
- }
-
- /**
- * Squishes the interpolation curve into the first half of the animation.
- */
- private static class StartCurveInterpolator extends AccelerateDecelerateInterpolator {
- @Override
- public float getInterpolation(float input) {
- return super.getInterpolation(Math.min(1, input * 2.0f));
- }
- }
}
diff --git a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java
index eed8d77..b5b6891 100644
--- a/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java
+++ b/third_party/android_swipe_refresh/java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java
@@ -441,13 +441,30 @@ public class SwipeRefreshLayout extends ViewGroup {
}
/**
+ * @deprecated Use {@link #setProgressBackgroundColorSchemeResource(int)}
+ */
+ @Deprecated
+ public void setProgressBackgroundColor(int colorRes) {
+ setProgressBackgroundColorSchemeResource(colorRes);
+ }
+
+ /**
* Set the background color of the progress spinner disc.
*
* @param colorRes Resource id of the color.
*/
- public void setProgressBackgroundColor(int colorRes) {
- mCircleView.setBackgroundColor(colorRes);
- mProgress.setBackgroundColor(getResources().getColor(colorRes));
+ public void setProgressBackgroundColorSchemeResource(int colorRes) {
+ setProgressBackgroundColorSchemeColor(getResources().getColor(colorRes));
+ }
+
+ /**
+ * Set the background color of the progress spinner disc.
+ *
+ * @param color
+ */
+ public void setProgressBackgroundColorSchemeColor(int color) {
+ mCircleView.setBackgroundColor(color);
+ mProgress.setBackgroundColor(color);
}
/**
@@ -596,7 +613,7 @@ public class SwipeRefreshLayout extends ViewGroup {
setAnimationProgress(overscrollTop / mTotalDragDistance);
}
}
- float strokeStart = (float) (adjustedPercent * .8f);
+ float strokeStart = adjustedPercent * .8f;
mProgress.setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, strokeStart));
mProgress.setArrowScale(Math.min(1f, adjustedPercent));
@@ -719,6 +736,7 @@ public class SwipeRefreshLayout extends ViewGroup {
targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
int offset = targetTop - mCircleView.getTop();
setTargetOffsetTopAndBottom(offset, false /* requires update */);
+ mProgress.setArrowScale(1 - interpolatedTime);
}
};