思路
主要步骤就是上升和爆炸。都是用属性动画实现的。使用属性动画的时候,该属性必须要有set和get方法。
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(boomView, "flyFraction", 0, 1);
objectAnimator.setDuration(700);
objectAnimator.setInterpolator(new DecelerateInterpolator());
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(boomView, "boomFraction", 0, 1);
objectAnimator1.setDuration(400);
final AnimatorSet set = new AnimatorSet();
set.playSequentially(objectAnimator, objectAnimator1);
boomView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
set.start();
}
});
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
//改变颜色
color = Color.argb(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
boomView.setColor(color);
DrawableCompat.setTint(imageView.getDrawable(),color);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
//循环播放
set.start();
}
});
上升过程
上升过程用canvas画一个矩形,从0-3/4高度。
if(flyFraction!=1){
int y = (int) ((1 - flyFraction * 3 / 4) * canvas.getHeight());
mPaint.setColor(color);
canvas.drawRect(canvas.getWidth() / 2 - 5, y, canvas.getWidth() / 2 + 5, y + 10, mPaint);
}
爆炸过程
爆炸粒子的围绕半径逐渐变大。(使用极坐标可以很容易地在画小圆点)
public class BoomUtil {
private Paint mPaint;
private int pointCount;//爆炸时的粒子数量
private int radiusMax;//最大爆炸半径
private int pointRadius;//粒子半径
public BoomUtil(int pointCount, int radiusMax, int pointRadius) {
this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.pointCount = pointCount;
this.radiusMax = radiusMax;
this.pointRadius = pointRadius;
}
public void drawBoom(Canvas canvas, int cx,int cy,float fraction,int color) {
mPaint.setColor(color);
mPaint.setAlpha((int) (255 * (1 - fraction)));
int radius = (int) (radiusMax * fraction);
for (int i = 0; i < pointCount; i++) {
double angle = i * 2 * Math.PI / pointCount;
float x = (float) Math.cos(angle) * radius+cx;
float y = (float) Math.sin(angle) * radius+cy;
canvas.drawCircle(x, y, pointRadius, mPaint);
}
}
}
BoomView
public class BoomView extends View {
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float flyFraction = 0;
private float boomFraction = 0;
private BoomUtil boomUtil;
private Random random;
private int color;
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public BoomView(Context context) {
super(context);
initBoomUtil();
}
public BoomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initBoomUtil();
}
private void initBoomUtil() {
boomUtil = new BoomUtil(12, 200, 12);
}
public float getBoomFraction() {
return boomFraction;
}
public void setBoomFraction(float boomFraction) {
this.boomFraction = boomFraction;
invalidate();
}
public float getFlyFraction() {
return flyFraction;
}
public void setFlyFraction(float flyFraction) {
this.flyFraction = flyFraction;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(flyFraction!=1){
int y = (int) ((1 - flyFraction * 3 / 4) * canvas.getHeight());
mPaint.setColor(color);
canvas.drawRect(canvas.getWidth() / 2 - 5, y, canvas.getWidth() / 2 + 5, y + 10, mPaint);
}
if (boomFraction != 0) {
boomUtil.drawBoom(canvas, canvas.getWidth() / 2, canvas.getHeight() / 4, boomFraction, color);
}
}
}
总结
把一个复杂的过程分解为多个简单的过程,思路瞬间清晰了。
github源码
网友评论