4,140

# 封装粒子

``````public class Particle {
public float x, y;
public float startXV;
public float startYV;
public float angle;
public float alpha;
public Bitmap bitmap;
public int width, height;
}
``````
• x，y是粒子的位置信息
• startXV，startYV是X方向和Y方向的速度
• angle是发散出去的角度
• alpha是粒子的透明度
• bitmap, width, height即粒子图片信息 我们在构造函数中初始化这些信息，给定一些默认值
``````public Particle(Bitmap originalBitmap) {
alpha = 1;
float scale = (float) Math.random() * 0.3f + 0.7f;
width = (int) (originalBitmap.getWidth() * scale);
height = (int) (originalBitmap.getHeight() * scale);
bitmap = Bitmap.createScaledBitmap(originalBitmap, width, height, true);

startXV = new Random().nextInt(150) * (new Random().nextBoolean() ? 1 : -1);
startYV = new Random().nextInt(170) * (new Random().nextBoolean() ? 1 : -1);
int i = new Random().nextInt(360);
angle = (float) (i * Math.PI / 180);

float rotate = (float) Math.random() * 180 - 90;
Matrix matrix = new Matrix();
matrix.setRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
originalBitmap.recycle();
}
``````

# 绘制粒子

``````public class ParticleView extends View {
Paint paint;
List<Particle> particles = new ArrayList<>();
//.....省略构造函数
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Particle particle : particles) {
paint.setAlpha((int) (particle.alpha * 255));
canvas.drawBitmap(particle.bitmap, particle.x - particle.width / 2, particle.y - particle.height / 2, paint);
}
}
public void setParticles(List<Particle> particles) {
this.particles = particles;
}
}
``````

# 管理粒子

``````private void startAnimator(View emiter) {
ValueAnimator valueAnimator = ObjectAnimator.ofInt(0, 1).setDuration(1000);
for (Particle particle : particles) {
particle.alpha = 1 - animation.getAnimatedFraction();
float time = animation.getAnimatedFraction();
time *= 10;
particle.x = startX - (float) (particle.startXV * time * Math.cos(particle.angle));
particle.y = startY - (float) (particle.startYV * time * Math.sin(particle.angle) - 9.8 * time * time / 2);
}
particleView.invalidate();
});
valueAnimator.start();
}
``````

``````public ParticleManager(Activity activity, int[] drawableIds) {
particles = new ArrayList<>();
for (int drawableId : drawableIds) {
}
topView = activity.findViewById(android.R.id.content);
topView.getLocationInWindow(parentLocation);
}
``````

``````public void start(View emiter) {
int[] location = new int[2];
emiter.getLocationInWindow(location);
startX = location[0] + emiter.getWidth() / 2 - parentLocation[0];
startY = location[1] - parentLocation[1];
particleView = new ParticleView(topView.getContext());
particleView.setParticles(particles);
startAnimator(emiter);
}
``````

# 使用

``````val ids = ArrayList<Int>()
for (index in 1..18) {
val id = resources.getIdentifier("img_like_\$index", "mipmap", packageName);
}
collectImage.setOnClickListener {
ParticleManager(this, ids.toIntArray())
.start(collectImage)
}
``````

``````valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation, boolean isReverse) {
}
@Override
public void onAnimationEnd(Animator animation) {
topView.removeView(particleView);
topView.postInvalidate();
}
@Override
public void onAnimationCancel(Animator animation) {
topView.removeView(particleView);
topView.postInvalidate();
}
});
``````