本文介绍一个好玩的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