SweepLoadingView-延时动画
这两天写了一个关于延时加载的控件,之前一直是用的 ProgressWheel, 后来参考了 lovejjfg 这个控件设计思路还是很巧妙的。不会用作图工具,凑合着看吧。 SweepLoadingView.png 怎么用? <pre> <github.alex.sweeploadingview.SweepLoadingView xmlns:SweepLoadingView="http://schemas.android.com/apk/res-auto" android:layout_width="112dp" android:layout_height="112dp" android:layout_centerHorizontal="true" android:layout_marginTop="72dp" SweepLoadingView:slv_circleColor="#795548" SweepLoadingView:slv_circleWidth="8dp" SweepLoadingView:slv_duration="1200" SweepLoadingView:slv_gapAngle="30" SweepLoadingView:slv_strokeCap="square" /> </pre> 效果图 001.gif 奉上源码 <pre> package github.alex.sweeploadingview; /** * 作者:Alex * * 时间:2016/8/24 16:31 * * 博客地址:http://www.jianshu.com/users/c3c4ea133871/subscriptions * * */ public class SweepLoadingView extends View { private RectF rectF; private Paint paint; private int circleColor; private int circleWidth; private int strokeCap; /** * 扫描一周 需要的时间 */ private int swipeDuration; /** * 起点的角度 */ private float startAngle; /** * 扫描的角度 */ private float sweepAngle; /\*\* \* 终点 和 起点的间隔 角度 \*/ private float gapAngle; /\*\* \* 起始点的偏移量 \*/ private float startAngleOffset; private ObjectAnimator sweepObjectAnimator; private ObjectAnimator startAngleObjectAnimator; /\*\* \* 扫描一周 \*/ private boolean isSweepRepeat; public SweepLoadingView(Context context) { super(context); initView(null); } public SweepLoadingView(Context context, AttributeSet attrs) { super(context, attrs); initView(attrs); } private void initView(AttributeSet attrs) { startAngleOffset = 0; isSweepRepeat = false; initObjectAnimation(); } private void initObjectAnimation() { sweepObjectAnimator = ObjectAnimator.ofFloat(this, new AngleProperty(Float.class, "sweepAngle"), 360F - gapAngle \* 2); sweepObjectAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); sweepObjectAnimator.setDuration(swipeDuration); sweepObjectAnimator.setRepeatCount(Integer.MAX_VALUE); sweepObjectAnimator.setRepeatMode(ValueAnimator.RESTART); sweepObjectAnimator.addListener(new SweepAngleAnimatorListener()); startAngleObjectAnimator = ObjectAnimator.ofFloat(this, new AngleProperty(Float.class, "startAngle"), 360F); startAngleObjectAnimator.setInterpolator(new LinearInterpolator()); startAngleObjectAnimator.setDuration(1500); startAngleObjectAnimator.setRepeatCount(Integer.MAX_VALUE); startAngleObjectAnimator.setRepeatMode(ValueAnimator.RESTART); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int min = Math.min(w, h); int dWidth = circleWidth / 2; rectF.left = dWidth; rectF.right = min - dWidth; rectF.top = dWidth; rectF.bottom = min - dWidth; } @Override public void draw(Canvas canvas) { super.draw(canvas); canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); float startAngle = this.startAngle - startAngleOffset; float sweepAngle = this.sweepAngle; if (isSweepRepeat) { startAngle += sweepAngle; sweepAngle = 360 - sweepAngle - gapAngle; } else { sweepAngle += gapAngle; } canvas.drawArc(rectF, startAngle, sweepAngle, false, paint); } private void startSweepAnimation() { if (!sweepObjectAnimator.isStarted()) { LogUtil.e("开始"); sweepObjectAnimator.start(); } if (!startAngleObjectAnimator.isStarted()) { startAngleObjectAnimator.start(); } } private void stopSweepAnimation() { LogUtil.e("停止"); sweepObjectAnimator.cancel(); startAngleObjectAnimator.cancel(); } private final class SweepAngleAnimatorListener extends SimpleAnimatorListener { @Override public void onAnimationRepeat(Animator animation) { handleSweepRepeat(); } } /\*\* \* 处理扫描一周的 情况 \*/ private void handleSweepRepeat() { if (isSweepRepeat) { startAngleOffset = (startAngleOffset + gapAngle \* 2) % 360; } isSweepRepeat = !isSweepRepeat; } private final class AngleProperty extends Property<SweepLoadingView, Float> { private String name; public AngleProperty(Class<Float> type, String name) { super(type, name); this.name = name; } @Override public Float get(SweepLoadingView object) { if ("sweepAngle".equals(name)) { return object.getSweepAngle(); } else { return object.getStartAngle(); } } @Override public void set(SweepLoadingView object, Float value) { if ("sweepAngle".equals(name)) { object.setSweepAngle(value); } else { object.setStartAngle(value); } } } private float getSweepAngle() { return sweepAngle; } private void setSweepAngle(float sweepAngle) { this.sweepAngle = sweepAngle; invalidate(); } private float getStartAngle() { return startAngle; } private void setStartAngle(float startAngle) { this.startAngle = startAngle; invalidate(); } } </pre>