本文介绍一个好玩的App 如图:
实现思路:在一个透明的Activity上用一个自定义View,然后在View上画.9的碎玻璃图片,加上音效。然后过一段时间消失。
主要用一个postInvalidate();方法,用一个集合去装手指触摸过的地方,在touch事件中调用postInvalidate();方法进行视图重新绘制。
需要注意的是,这里的播放音效和上篇博客 Android 闪电效果 (Electric Screen,电动屏幕) 中的播放音效一样,暂停音效的时候要传开始播放时得到的int返回值,和停止音效不一样。
可以通过限制集合长度来限制绘制的屏幕个数。
单独开启一个线程,过一段时间开始清除效果, 即直接操作集合,操作完了调用postInvalidate(); 重新绘图就可以了。
示例代码:
public class CustomView extends View { private Paint mPaint; private SoundPool mSoundPool; private Map<Integer, Integer> mSoundMap = new HashMap<Integer, Integer>(); private int mIndex; private Bitmap mBitmap; private ArrayList<Float> mXPointList; private ArrayList<Float> mYPointList; private int mCount = 0;// 点击次数 private int mLength = 30;// 绘制总数 public CustomView(Context context, AttributeSet attrs) { super(context); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.BLUE); // mPaint.setAlpha(127); mPaint.setStrokeWidth(2.0f); this.setKeepScreenOn(true); this.setFocusable(true); this.setLongClickable(true); this.mSoundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 5); this.mSoundMap.put(1, mSoundPool.load(context, R.raw.cfokwowbfv, 1)); this.mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.screen); mXPointList = new ArrayList<Float>(); mYPointList = new ArrayList<Float>(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub while (true) { try { Thread.sleep(4000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // mG++; handler.sendEmptyMessage(0); } } }).start(); } @Override public boolean onTouchEvent(MotionEvent arg1) { // TODO Auto-generated method stub switch (arg1.getAction()) { case MotionEvent.ACTION_DOWN: // drawBitmap(arg1.getX(), arg1.getY()); playSound(); mXPointList.add(arg1.getX()); mYPointList.add(arg1.getY()); postInvalidate(); mCount++; if (mCount > mLength) { mXPointList.remove(0); mYPointList.remove(0); mLength++; } break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; default: break; } return super.onTouchEvent(arg1); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < mXPointList.size(); ++i) { canvas.drawBitmap(mBitmap, mXPointList.get(i) - mBitmap.getWidth() / 2, mYPointList.get(i) - mBitmap.getHeight() / 2, null); } } // 播放 public void playSound() { mIndex = mSoundPool.play(mSoundMap.get(1), 1, 1, 0, 0, 1); } // 停止播放 public void stopSound() { // Toast.makeText(getContext(), "zzzzz", 0).show(); mSoundPool.stop(mIndex); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub Toast.makeText(getContext(), "keydown", Toast.LENGTH_SHORT).show(); return super.onKeyDown(keyCode, event); } // 更新界面 Handler handler = new Handler() { public void handleMessage(Message msg) { if (msg.what == 0) { if (mCount != 0 && mXPointList.size() != 0) { for (int i = 0; i < new Random() .nextInt(mXPointList.size() + 1); i++) { mXPointList.remove(0); mYPointList.remove(0); mLength++; } } postInvalidate(); } } };}
Github: https://github.com/OneHead/crack_screen2D
Weibo: http://weibo.com/2382477985