首页 > 代码库 > Android 碎屏效果 (Crack Screen,击碎屏幕)

Android 碎屏效果 (Crack Screen,击碎屏幕)

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

Android 碎屏效果 (Crack Screen,击碎屏幕)