尝试替换SwipeRefreshLayout的下拉动画
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user