前言:最近接到一个任务,就是自定义一个Drawable以实现progressbar的加载效果,如图: ![]java
要完成这个任务难点有二。 第一点:经过canvas和path绘制连续的颜色不一样的平行四边形 第二点:让这一系列的平行四边形动起来(利用valueanimator,在添加它的状态改变的监听,并调用invalidateSelf();刷新Drawable的draw方法) 下面直接上代码,应该能够看得懂:canvas
public class ColorfulProgressLoadingDrawable extends Drawable { private double unitHeight; private double unitSize; private int colorA; private int colorB; private int windowSize = 0; private float offset = 0; public ValueAnimator mValueAnimator; Path path = new Path(); ``` //colorA、B为两种传入的颜色 public ColorfulProgressLoadingDrawable(int windowSize, double unitHeight, int colorA, int colorB) { this.windowSize = windowSize; this.unitHeight = unitHeight; this.colorA = colorA; this.colorB = colorB; this.unitSize = Math.sqrt(unitHeight * unitHeight / 3); } [@Override](https://my.oschina.net/u/1162528) public void draw([@NonNull](https://my.oschina.net/u/2981441) Canvas canvas) { ``` //此方法设置path,path为平行四边形 Paint paint = new Paint(); for (int i = 0; i < getShapeNumber(); i++) { if ((i + 1) % 2 == 1) { paint.setColor(colorA); } else { paint.setColor(colorB); } path.reset(); path.moveTo((float) (offset + windowSize - unitSize * i), 0); path.lineTo((float) (offset + windowSize - unitSize - unitSize * i), 0); path.lineTo((float) (offset + windowSize - 2 * unitSize - unitSize * i), (float) unitHeight); path.lineTo((float) (offset + windowSize - unitSize - unitSize * i), (float) unitHeight); canvas.drawPath(path, paint); } ``` } [@Override](https://my.oschina.net/u/1162528) public void setAlpha(int alpha) { } [@Override](https://my.oschina.net/u/1162528) public void setColorFilter([@Nullable](https://my.oschina.net/u/2896689) ColorFilter colorFilter) { } @Override public int getOpacity() { return PixelFormat.OPAQUE; } //计算要绘制的平行四边形的个数 private int getShapeNumber() { return (int) (2 * (windowSize / unitSize)); } public void startAnimator() {; initValueAnimator(); mValueAnimator.start(); } private void initValueAnimator(){ if (mValueAnimator==null) { mValueAnimator = ValueAnimator.ofFloat(0, 4 * (float) unitSize); mValueAnimator.setInterpolator(new LinearInterpolator()); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { LogUtils.e("" + animation.getAnimatedValue()); offset = (float) animation.getAnimatedValue(); invalidateSelf(); } }); mValueAnimator.setDuration(1000); mValueAnimator.setRepeatCount(ValueAnimator.INFINITE); mValueAnimator.setRepeatMode(ValueAnimator.RESTART); } } public void stopAnimator() { if (mValueAnimator == null) { return; } else { mValueAnimator.cancel(); } } }
注意:在对Drawable进行引用的时候需调用startAnimator()开始动画,以及在适当的时候调用stopAnimator来结束动画以防止内存泄露。ide