前言:最近接到一个任务,就是自定义一个Drawable以实现progressbar的加载效果,如图: ![]
要完成这个任务难点有二。 第一点:通过canvas和path绘制连续的颜色不同的平行四边形 第二点:让这一系列的平行四边形动起来(利用valueanimator,在添加它的状态改变的监听,并调用invalidateSelf();刷新Drawable的draw方法) 下面直接上代码,应该可以看得懂:
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来结束动画以防止内存泄露。