尝试替换SwipeRefreshLayout的下拉动画

This commit is contained in:
kehaoyuan
2020-07-20 17:58:51 +08:00
parent b38032074b
commit 466e118579

View File

@ -18,8 +18,11 @@ package androidx.swiperefreshlayout.widget;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@ -41,6 +44,9 @@ import androidx.annotation.RestrictTo;
import androidx.core.util.Preconditions;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import com.gh.gamecenter.R;
import com.halo.assistant.HaloApp;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -67,14 +73,18 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
/** @hide */
/**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
@Retention(RetentionPolicy.SOURCE)
@IntDef({LARGE, DEFAULT})
public @interface ProgressDrawableSize {
}
/** Maps to ProgressBar.Large style. */
/**
* Maps to ProgressBar.Large style.
*/
public static final int LARGE = 0;
private static final float CENTER_RADIUS_LARGE = 11f;
@ -82,7 +92,9 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
private static final int ARROW_WIDTH_LARGE = 12;
private static final int ARROW_HEIGHT_LARGE = 6;
/** Maps to ProgressBar default style. */
/**
* Maps to ProgressBar default style.
*/
public static final int DEFAULT = 1;
private static final float CENTER_RADIUS = 7.5f;
@ -105,36 +117,51 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
private static final float COLOR_CHANGE_OFFSET = 0.75f;
private static final float SHRINK_OFFSET = 0.5f;
/** The duration of a single progress spin in milliseconds. */
private static final int ANIMATION_DURATION = 1332;
/**
* The duration of a single progress spin in milliseconds.
*/
private static final int ANIMATION_DURATION = 1700;
/** Full rotation that's done for the animation duration in degrees. */
/**
* Full rotation that's done for the animation duration in degrees.
*/
private static final float GROUP_FULL_ROTATION = 1080f / 5f;
/** The indicator ring, used to manage animation state. */
/**
* The indicator ring, used to manage animation state.
*/
private final Ring mRing;
/** Canvas rotation in degrees. */
/**
* Canvas rotation in degrees.
*/
private float mRotation;
/** Maximum length of the progress arc during the animation. */
/**
* Maximum length of the progress arc during the animation.
*/
private static final float MAX_PROGRESS_ARC = .8f;
/** Minimum length of the progress arc during the animation. */
/**
* Minimum length of the progress arc during the animation.
*/
private static final float MIN_PROGRESS_ARC = .01f;
/** Rotation applied to ring during the animation, to complete it to a full circle. */
/**
* Rotation applied to ring during the animation, to complete it to a full circle.
*/
private static final float RING_ROTATION = 1f - (MAX_PROGRESS_ARC - MIN_PROGRESS_ARC);
private Resources mResources;
private Animator mAnimator;
@SuppressWarnings("WeakerAccess") /* synthetic access */
float mRotationCount;
float mRotationCount;
@SuppressWarnings("WeakerAccess") /* synthetic access */
boolean mFinishing;
boolean mFinishing;
/**
* @param context application context
*/
@SuppressLint("RestrictedApi")
public CircularProgressDrawable(@NonNull Context context) {
mResources = Preconditions.checkNotNull(context).getResources();
@ -145,9 +172,11 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
setupAnimators();
}
/** Sets all parameters at once in dp. */
/**
* Sets all parameters at once in dp.
*/
private void setSizeParameters(float centerRadius, float strokeWidth, float arrowWidth,
float arrowHeight) {
float arrowHeight) {
final Ring ring = mRing;
final DisplayMetrics metrics = mResources.getDisplayMetrics();
final float screenDensity = metrics.density;
@ -254,7 +283,7 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
/**
* Sets the dimensions of the arrow at the end of the spinner in pixels.
*
* @param width width of the baseline of the arrow in pixels
* @param width width of the baseline of the arrow in pixels
* @param height distance from tip of the arrow to its baseline in pixels
*/
public void setArrowDimensions(float width, float height) {
@ -324,7 +353,7 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
* at 1.
*
* @param start starting position of the arc from [0..1]
* @param end ending position of the arc from [0..1]
* @param end ending position of the arc from [0..1]
*/
public void setStartEndTrim(float start, float end) {
mRing.setStartTrim(start);
@ -398,8 +427,9 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
public void draw(Canvas canvas) {
final Rect bounds = getBounds();
canvas.save();
canvas.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
mRing.draw(canvas, bounds);
// canvas.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
mRing.draw(canvas, bounds, mAnimator);
canvas.restore();
}
@ -448,7 +478,7 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
// Already showing some part of the ring
if (mRing.getEndTrim() != mRing.getStartTrim()) {
mFinishing = true;
mAnimator.setDuration(ANIMATION_DURATION / 2);
mAnimator.setDuration(ANIMATION_DURATION);
mAnimator.start();
} else {
mRing.setColorIndex(0);
@ -531,6 +561,8 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
*/
@SuppressWarnings("WeakerAccess") /* synthetic access */
void applyTransformation(float interpolatedTime, Ring ring, boolean lastFrame) {
ring.setInterpolatedTime(interpolatedTime);
if (mFinishing) {
applyFinishTranslation(interpolatedTime, ring);
// Below condition is to work around a ValueAnimator issue where onAnimationRepeat is
@ -647,6 +679,59 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
int mAlpha = 255;
int mCurrentColor;
float mInterpolatedTime = 0F;
private int[] images = {
R.drawable.refresh_01, R.drawable.refresh_02,
R.drawable.refresh_03, R.drawable.refresh_04,
R.drawable.refresh_05, R.drawable.refresh_06,
R.drawable.refresh_07, R.drawable.refresh_08,
R.drawable.refresh_09, R.drawable.refresh_10,
R.drawable.refresh_11, R.drawable.refresh_12,
R.drawable.refresh_13, R.drawable.refresh_14,
R.drawable.refresh_15, R.drawable.refresh_16,
R.drawable.refresh_17, R.drawable.refresh_18,
R.drawable.refresh_19, R.drawable.refresh_20,
R.drawable.refresh_21, R.drawable.refresh_22,
R.drawable.refresh_23, R.drawable.refresh_24,
R.drawable.refresh_25, R.drawable.refresh_26,
R.drawable.refresh_27, R.drawable.refresh_28,
R.drawable.refresh_29, R.drawable.refresh_30,
R.drawable.refresh_31, R.drawable.refresh_32,
R.drawable.refresh_33, R.drawable.refresh_34,
R.drawable.refresh_35, R.drawable.refresh_36,
R.drawable.refresh_37, R.drawable.refresh_38,
R.drawable.refresh_39, R.drawable.refresh_40,
R.drawable.refresh_41, R.drawable.refresh_42,
R.drawable.refresh_43, R.drawable.refresh_44,
R.drawable.refresh_45, R.drawable.refresh_46,
R.drawable.refresh_47, R.drawable.refresh_48,
R.drawable.refresh_49, R.drawable.refresh_50,
R.drawable.refresh_51, R.drawable.refresh_52,
R.drawable.refresh_53, R.drawable.refresh_54,
R.drawable.refresh_55, R.drawable.refresh_56,
R.drawable.refresh_57, R.drawable.refresh_58,
R.drawable.refresh_59, R.drawable.refresh_60,
R.drawable.refresh_61, R.drawable.refresh_62,
R.drawable.refresh_63, R.drawable.refresh_64,
R.drawable.refresh_65, R.drawable.refresh_66,
R.drawable.refresh_67, R.drawable.refresh_68,
R.drawable.refresh_69, R.drawable.refresh_70,
R.drawable.refresh_71, R.drawable.refresh_72,
R.drawable.refresh_73, R.drawable.refresh_74,
R.drawable.refresh_75, R.drawable.refresh_76,
R.drawable.refresh_77, R.drawable.refresh_78,
R.drawable.refresh_79, R.drawable.refresh_80,
R.drawable.refresh_81, R.drawable.refresh_82,
R.drawable.refresh_83, R.drawable.refresh_84,
R.drawable.refresh_85, R.drawable.refresh_86,
R.drawable.refresh_87, R.drawable.refresh_88,
R.drawable.refresh_89, R.drawable.refresh_90,
R.drawable.refresh_91, R.drawable.refresh_92,
R.drawable.refresh_93, R.drawable.refresh_94,
R.drawable.refresh_95, R.drawable.refresh_96,
R.drawable.refresh_97, R.drawable.refresh_98};
Ring() {
mPaint.setStrokeCap(Paint.Cap.SQUARE);
mPaint.setAntiAlias(true);
@ -661,7 +746,7 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
/**
* Sets the dimensions of the arrowhead.
*
* @param width width of the hypotenuse of the arrow head
* @param width width of the hypotenuse of the arrow head
* @param height height of the arrow point
*/
void setArrowDimensions(float width, float height) {
@ -688,7 +773,7 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
/**
* Draw the progress spinner
*/
void draw(Canvas c, Rect bounds) {
void draw(Canvas c, Rect bounds, Animator animator) {
final RectF arcBounds = mTempBounds;
float arcRadius = mRingCenterRadius + mStrokeWidth / 2f;
if (mRingCenterRadius <= 0) {
@ -711,13 +796,29 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
// Draw the background first
float inset = mStrokeWidth / 2f; // Calculate inset to draw inside the arc
arcBounds.inset(inset, inset); // Apply inset
c.drawCircle(arcBounds.centerX(), arcBounds.centerY(), arcBounds.width() / 2f,
mCirclePaint);
// c.drawCircle(arcBounds.centerX(), arcBounds.centerY(), arcBounds.width() / 2f,
// mCirclePaint);
arcBounds.inset(-inset, -inset); // Revert the inset
c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
// c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
drawTriangle(c, startAngle, sweepAngle, arcBounds);
// drawTriangle(c, startAngle, sweepAngle, arcBounds);
drawImageToRing(c, bounds, animator);
}
void drawImageToRing(Canvas canvas, Rect bounds, Animator animator) {
Bitmap bitmap;
Resources resources = HaloApp.getInstance().getApplication().getResources();
int offset = (int) (mInterpolatedTime * 100);
if (!animator.isRunning()) {
bitmap = BitmapFactory.decodeResource(resources, R.drawable.refresh_icon);
canvas.drawBitmap(bitmap, bounds, bounds, mPaint);
} else if (offset < 98) {
bitmap = BitmapFactory.decodeResource(resources, images[offset]);
canvas.drawBitmap(bitmap, bounds, bounds, mPaint);
}
}
void drawTriangle(Canvas c, float startAngle, float sweepAngle, RectF bounds) {
@ -920,6 +1021,10 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
return mArrowScale;
}
void setInterpolatedTime(float interpolatedTime) {
mInterpolatedTime = interpolatedTime;
}
/**
* @return The amount the progress spinner is currently rotated, between [0..1].
*/
@ -947,6 +1052,7 @@ public class CircularProgressDrawable extends Drawable implements Animatable {
setStartTrim(0);
setEndTrim(0);
setRotation(0);
setInterpolatedTime(0);
}
}
}
}