碎片化 《消消樂》
阿新 • • 發佈:2018-12-21
MainActivity
public class MainActivity extends AppCompatActivity { private Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); }catch (Exception e){ Log.d("TAG","異常"+e); } final ParticleView particleAnimator = new ParticleView(MainActivity.this,1000); particleAnimator.setOnAnimationListener(new ParticleView.OnAnimationListener() { @Override public void onAnimationStart(View view, Animator animation) { view.setVisibility(View.INVISIBLE); } @Override public void onAnimationEnd(View view,Animator animation) { } }); findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v1) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); findViewById(R.id.haha).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); particleAnimator.boom(v1); particleAnimator.boom(v); } }); } }); findViewById(R.id.haha).setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v1) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); particleAnimator.boom(v1); particleAnimator.boom(v); } }); } }); findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v1) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); particleAnimator.boom(v1); particleAnimator.boom(v); } }); } }); findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v1) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"haha",Toast.LENGTH_SHORT).show(); particleAnimator.boom(v1); particleAnimator.boom(v); } }); } }); } }
Particle
public class Particle { //預設小球寬高 public static final int PART_WH = 8; //x值 public float cx; //y值 public float cy; //繪製圓的半徑 public float radius; //顏色 public int color; //透明度 public float alpha; //用於生成隨機數 static Random random = new Random(); //粒子所在的矩形區域 public Rect mBound; public static Particle generateParticle(int color, Rect bound, Point point) { int row = point.y; //行是高 int column = point.x; //列是寬 Particle particle = new Particle(); particle.mBound = bound; particle.color = color; particle.alpha = 1f; particle.radius = PART_WH; particle.cx = bound.left + PART_WH * column; particle.cy = bound.top + PART_WH * row; return particle; } public void update(float factor) { cx = cx + factor * random.nextInt(mBound.width()) * (random.nextFloat() - 0.5f); cy = cy + factor * (mBound.height()/(random.nextInt(4)+1)) ; radius = radius - factor * random.nextInt(3);; if (radius<=0) radius = 0; alpha = 1f - factor; } public static Particle[][] generateParticles(Bitmap bitmap, Rect bound) { int w = bound.width(); int h = bound.height(); int partW_Count = w / Particle.PART_WH; int partH_Count = h / Particle.PART_WH; Particle[][] particles = new Particle[partH_Count][partW_Count]; Point point = null; for (int row = 0; row < partH_Count; row ++) { //行 for (int column = 0; column < partW_Count; column ++) { //列 //取得當前粒子所在位置的顏色 int color = bitmap.getPixel(column * Particle.PART_WH, row * Particle.PART_WH); point = new Point(column, row); //x是列,y是行 particles[row][column] = Particle.generateParticle(color, bound, point); } } return particles; } }
ParticleView
public class ParticleView extends View { private ValueAnimator mParticleAnimator; //動畫持續時間 public int DURATION = 2000; //動畫監聽 private OnAnimationListener mOnAnimationListener; //畫筆 private Paint mPaint; //所有粒子 private Particle[][] mParticles; public void setOnAnimationListener(OnAnimationListener mOnAnimationListener) { this.mOnAnimationListener = mOnAnimationListener; } public ParticleView(Context context) { super(context); init(); } /** * * @param context * @param durtion 動畫時間 */ public ParticleView(Context context, int durtion) { super(context); this.DURATION = durtion; init(); } public ParticleView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { attachToActivity((Activity) getContext()); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { if (mParticleAnimator !=null) drawParticle(canvas); } public void drawParticle(Canvas canvas) { for (Particle[] particle : mParticles) { for (Particle p : particle) { p.update((Float) mParticleAnimator.getAnimatedValue()); mPaint.setColor(p.color); mPaint.setAlpha((int) (Color.alpha(p.color) * p.alpha)); canvas.drawCircle(p.cx, p.cy, p.radius, mPaint);// } } } public void boom(final View view) { if(view.getVisibility()!=View.VISIBLE||view.getAlpha()==0 ||(mParticleAnimator!=null && mParticleAnimator.isRunning())){ return; } view.post(new Runnable() { @Override public void run() { int[] location = new int[2]; view.getLocationInWindow(location); Rect rect = new Rect(location[0],location[1],location[0]+view.getMeasuredWidth(),location[1]+view.getMeasuredHeight()); mParticles = Particle.generateParticles(getCacheBitmapFromView(view), rect); mParticleAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); mParticleAnimator.setDuration(DURATION); mParticleAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { if (mOnAnimationListener!=null) mOnAnimationListener.onAnimationStart(view,animation); } @Override public void onAnimationEnd(Animator animation) { if (mOnAnimationListener!=null) mOnAnimationListener.onAnimationEnd(view,animation); } }); mParticleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { invalidate(); } }); mParticleAnimator.start(); } }); } /** * 獲取一個 View 的快取檢視 * * @param view * @return */ private Bitmap getCacheBitmapFromView(View view) { final boolean drawingCacheEnabled = true; view.setDrawingCacheEnabled(drawingCacheEnabled); view.buildDrawingCache(drawingCacheEnabled); final Bitmap drawingCache = view.getDrawingCache(); Bitmap bitmap; if (drawingCache != null) { bitmap = Bitmap.createBitmap(drawingCache); view.setDrawingCacheEnabled(false); } else { bitmap = null; } return bitmap; } private void attachToActivity(Activity activity) { ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView(); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); rootView.addView(this, lp); } public interface OnAnimationListener{ //當前正在執行的view void onAnimationStart(View v,Animator animation); void onAnimationEnd(View v,Animator animation); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:orientation="vertical" > <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="wrap_content" android:layout_height="wrap_content"> </android.support.v7.widget.Toolbar> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <Button android:layout_width="70dp" android:layout_height="70dp" android:layout_margin="15dp" android:gravity="center" android:id="@+id/btn1" android:text="點我" /> <Button android:layout_width="70dp" android:layout_height="70dp" android:layout_margin="15dp" android:gravity="center" android:id="@+id/btn2" android:text="點我" /> <Button android:id="@+id/haha" android:layout_width="60dp" android:layout_height="60dp" android:layout_margin="15dp" android:gravity="center" android:background="#f60" android:text="哈哈" /> /> <Button android:id="@+id/btn" android:layout_width="60dp" android:layout_height="60dp" android:layout_margin="15dp" android:gravity="center" android:background="#f60" android:text="哈哈" /> </LinearLayout> </ScrollView> </LinearLayout>