Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android實現刮刮樂效果

Android實現刮刮樂效果

編輯:關於Android編程

前幾個月剛接觸Android的時候做了一個小項目,其中也用到了類似刮刮樂的效果,現在把代碼貼出來

首先要做一個類似橡皮擦的東西吧,然後才能把紙上的筆跡擦除

/**
 * FileName: SplashActivity.java
 * 
 * @desc 橡皮擦功能,類似刮刮樂效果
 * @author HTP
 * @Date 20140311
 * @version 1.00
 */
public class Text_Rubbler extends TextView {

	private float TOUCH_TOLERANCE; // 填充距離,使線條更自然,柔和,值越小,越柔和。

	// private final int bgColor;
	// 位圖
	private Bitmap mBitmap;
	// 畫布
	private Canvas mCanvas;
	// 畫筆
	private Paint mPaint;
	private Path mPath;
	private float mX, mY;

	private boolean isDraw = false;

	public Text_Rubbler(Context context) {
		/**
		 * @param context 上下文
		 */
		super(context);

	}

	public Text_Rubbler(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// bgColor =
		// attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android",
		// "textColor", 0xFFFFFF);
		// System.out.println("Color:"+bgColor);
	}

	public Text_Rubbler(Context context, AttributeSet attrs) {
		super(context, attrs);
		// bgColor =
		// attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android",
		// "textColor", 0xFFFFFF);
		// System.out.println(bgColor);
		// System.out.println(attrs.getAttributeValue("http://schemas.android.com/apk/res/android",
		// "layout_width"));
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if (isDraw) {

			mCanvas.drawPath(mPath, mPaint);
			// mCanvas.drawPoint(mX, mY, mPaint);
			canvas.drawBitmap(mBitmap, 0, 0, null);
		}
	}

	/**
	 * 開啟檫除功能
	 * 
	 * @param bgColor
	 *            覆蓋的背景顏色
	 * @param paintStrokeWidth
	 *            觸點(橡皮)寬度
	 * @param touchTolerance
	 *            填充距離,值越小,越柔和。
	 */
	public void beginRubbler(final int bgColor, final int paintStrokeWidth,
			float touchTolerance) {
		TOUCH_TOLERANCE = touchTolerance;
		// 設置畫筆
		mPaint = new Paint();
		// mPaint.setAlpha(0);
		// 畫筆劃過的痕跡就變成透明色了
		mPaint.setColor(Color.BLACK); // 此處不能為透明色
		mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
		// 或者
		// mPaint.setAlpha(0);
		// mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圓角
		mPaint.setStrokeCap(Paint.Cap.ROUND); // 後圓角
		mPaint.setStrokeWidth(paintStrokeWidth); // 筆寬

		// 痕跡
		mPath = new Path();
		;
		// 覆蓋
		// if (getLayoutParams().width == LayoutParams.FILL_PARENT) {
		//
		// }
		mBitmap = Bitmap.createBitmap(getLayoutParams().width,
				getLayoutParams().height, Config.ARGB_8888);
		mCanvas = new Canvas(mBitmap);

		mCanvas.drawColor(bgColor);
		isDraw = true;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (!isDraw) {
			return true;
		}
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN: // 觸點按下
			// touchDown(event.getRawX(),event.getRawY());
			touchDown(event.getX(), event.getY());
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE: // 觸點移動
			touchMove(event.getX(), event.getY());
			invalidate();
			break;
		case MotionEvent.ACTION_UP: // 觸點彈起
			touchUp(event.getX(), event.getY());
			invalidate();
			break;
		default:
			break;
		}
		return true;
	}

	private void touchDown(float x, float y) {
		mPath.reset();
		mPath.moveTo(x, y);
		mX = x;
		mY = y;
	}

	private void touchMove(float x, float y) {
		float dx = Math.abs(x - mX);
		float dy = Math.abs(y - mY);
		if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
			mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
			mX = x;
			mY = y;
		}

	}

	private void touchUp(float x, float y) {
		mPath.lineTo(x, y);
		mCanvas.drawPath(mPath, mPaint);
		mPath.reset();
	}

}

接下來就是使用橡皮檫擦除了

/**
 * FileName: RubblerAct.java
 * @Desc  	該類通過調用Text_Rubbler這個類將在Activity上顯示一片刮一刮的區域,可以出發觸摸事件
 * @author  HTP
 * @Date   	20140312
 * @version 1.00 
 */


public class RubblerAct extends Activity {
	// 刮開後文字顯示
	private TextView tv_rubbler;
	// 得到刮一刮的內容
	private Sentence mSentence;
	// 下一張
	private TextView tv_next;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// setContentView(new Rubble(this,"謝謝惠顧",new Rect(100, 200,
		// 300,250),2,1f,14));

		// /////////////////////////////////////////
		setContentView(R.layout.rubbler);
		// 設置的顏色必須要有透明度。
		((Text_Rubbler) findViewById(R.id.rubbler)).beginRubbler(0xFFFFFFFF, 20,
				1f);// 設置橡皮擦的寬度等
		mSentence = new Sentence();
		// 隨機初始化文字
		tv_rubbler = (TextView) findViewById(R.id.rubbler);
		String str = mSentence.getSentence();
		tv_rubbler.setText(str);

		tv_next = (TextView) findViewById(R.id.tv_next);

		// 點擊下一步
		tv_next.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String str = mSentence.getSentence();
				tv_rubbler.setText(str);
				((Text_Rubbler) findViewById(R.id.rubbler))// 初始化狀態
						.beginRubbler(0xFFFFFFFF, 20, 1f);

			}
		});

	}

	class Rubble extends View {

		private final int PAINT_STROKE_WIDTH;
		private final float TOUCH_TOLERANCE; // 填充距離,使線條更自然,柔和,值越小,越柔和。
		private final int TEXT_SIZE;

		private Bitmap mBitmap;
		// 畫布
		private Canvas mCanvas;
		// 畫筆
		private Paint mPaint;
		private Path mPath;
		private float mX, mY;
		private final int X, Y, W, H;

		private final Rect touchRect;

		public Rubble(Context context, String bgText, Rect rect,
				int paintStrokeWidth, float touchTolerance, int textSize) {
			super(context);
			setFocusable(true);
			touchRect = rect;
			W = rect.right - rect.left;
			H = rect.bottom - rect.top;
			X = rect.left;
			Y = rect.top;
			TEXT_SIZE = textSize;
			PAINT_STROKE_WIDTH = paintStrokeWidth;
			TOUCH_TOLERANCE = touchTolerance;
			setBackground(touchRect, bgText);
			initDrowTools();

		}

		private void setBackground(Rect rect, String bgText) {
			DisplayMetrics dm = new DisplayMetrics();
			dm = this.getResources().getDisplayMetrics();

			Bitmap bitmap = Bitmap.createBitmap(dm.widthPixels,
					dm.heightPixels, Config.ARGB_8888);
			Canvas canvas = new Canvas(bitmap);

			Paint paint = new Paint();
			paint.setColor(0x88000000);
			// paint.setStyle(Style.STROKE);
			// paint.setTextAlign(Align.CENTER);
			paint.setTextSize(TEXT_SIZE);

			// paint.setTextScaleX(1.5f);
			canvas.drawColor(Color.WHITE);
			// 畫字的坐標不好控制
			int x = rect.left
					+ (rect.right - rect.left - bgText.length() * TEXT_SIZE)
					/ 2;
			int y = rect.top + (rect.bottom - rect.top - TEXT_SIZE) / 2;
			// int y = 218+25;
			canvas.drawText(bgText, x, y, paint);
			Drawable drawable = new BitmapDrawable(bitmap);
			setBackgroundDrawable(drawable);
		}

		private void initDrowTools() {
			// 設置畫筆
			mPaint = new Paint();
			// mPaint.setAlpha(0);
			// 畫筆劃過的痕跡就變成透明色了
			mPaint.setColor(Color.BLACK); // 此處不能為透明色
			mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
			// 或者
			// mPaint.setAlpha(0);
			// mPaint.setXfermode(new
			// PorterDuffXfermode(PorterDuff.Mode.DST_IN));

			mPaint.setAntiAlias(true);
			mPaint.setDither(true);
			mPaint.setStyle(Paint.Style.STROKE);
			mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圓角
			mPaint.setStrokeCap(Paint.Cap.ROUND); // 後圓角
			mPaint.setStrokeWidth(PAINT_STROKE_WIDTH); // 筆寬

			// 痕跡
			mPath = new Path();
			;

			// 覆蓋
			mBitmap = Bitmap.createBitmap(W, H, Config.ARGB_8888);
			mCanvas = new Canvas(mBitmap);
			mCanvas.drawColor(0x88000000);

		}

		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			mCanvas.drawPath(mPath, mPaint);
			// mCanvas.drawPoint(mX, mY, mPaint);
			canvas.drawBitmap(mBitmap, X, Y, null);
		}

		@Override
		public boolean onTouchEvent(MotionEvent event) {
			System.out.print("X--" + event.getX());
			System.out.println("Y--" + event.getY());
			if (!touchRect.contains((int) event.getX(), (int) event.getY())) {
				return false;
			}

			switch (event.getAction()) {
			// 觸點按下
			case MotionEvent.ACTION_DOWN: {
				touchDown(event.getRawX(), event.getRawY());
				touchDown(event.getX() - touchRect.left, event.getY()
						- touchRect.top);
				invalidate();
				break;
			}
				
			case MotionEvent.ACTION_MOVE: // 觸點移動
				touchMove(event.getX() - touchRect.left, event.getY()
						- touchRect.top);

				invalidate();
				break;
			case MotionEvent.ACTION_UP: // 觸點彈起
				touchUp(event.getX() - touchRect.left, event.getY()
						- touchRect.top);
				invalidate();
				break;
			default:
				break;
			}
			return true;
		}

		private void touchDown(float x, float y) {
			mPath.reset();
			mPath.moveTo(x, y);
			mX = x;
			mY = y;
		}

		private void touchMove(float x, float y) {
			float dx = Math.abs(x - mX);
			float dy = Math.abs(y - mY);
			if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
				mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
				mX = x;
				mY = y;
			}

		}

		private void touchUp(float x, float y) {
			mPath.lineTo(x, y);
			mCanvas.drawPath(mPath, mPaint);
			mPath.reset();
		}

	}

	/**
	 * 鍵盤事件,當按下back鍵的時候詢問是否再按一次退出程序
	 */
	// 退出時間
	private long exitTime = 0;
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK
				&& event.getAction() == KeyEvent.ACTION_DOWN) {
			if ((System.currentTimeMillis() - exitTime) > 2000) {
				Toast.makeText(getApplicationContext(), "再按一次退出程序",
						Toast.LENGTH_SHORT).show();
				exitTime = System.currentTimeMillis();
			} else {
				finish();
				System.exit(0);

			}
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

}

實現效果如下:


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved