android自定义控件 橡皮擦

先来张效果图哈,  我们可以在上面随意的擦擦擦~~~~



先跟大家讲一下实现的原理哈,  这里我们主要用到了 paint.setXfermode(PorterDuffXfermode portermode) ,设置画笔的混合模式,这里模式有十多种, 我就不贴图了. 大家可以自行百度~~

思路 :我们需要自己的new Canvas(bitmap) 来注入前景bitmap, 在onDraw方法里面 利用canvas 画出前景bitmap和背景bitmap.  然后利用自己mCanvas.drawPath(mPath,mPaint) 来改变效果.


这里我们使用了 PorterDuff.Mode.DST_IN 模式, 代表为上层下层重合处 显示下层.

利用的就是这么多了. 大家看代码吧. 一扫就会咯~

public class Eraser extends View {
	
		private PorterDuffXfermode portermode;
		private Canvas mCanvas;
		private Bitmap forgBitmap;
		private Bitmap backgBitmap;
		private Path mPath;
	
		private Paint mPaint;
		private int sW;
		private int sH;
		private Activity mContext;
		private DisplayMetrics outMetrics;
	
		private float preX; // 上一个X
		private float preY; // 上一个Y
		private static final int MOVE_DISTANCE = 5;
	
		public Eraser(Context context, AttributeSet attrs) {
			super(context, attrs);
			this.mContext = (Activity) context;
			calc();
			initView(context);
		}
	
		/**
		 * 计算屏幕高度
		 */
		private void calc() {
			outMetrics = new DisplayMetrics();
			mContext.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
			sW = outMetrics.widthPixels;
			sH = outMetrics.heightPixels;
		}
	
		private void initView(Context context) {
			mPath = new Path();
			
			mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); // 抗锯齿,抗抖动
			mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
			mPaint.setARGB(128, 255, 0, 0);
			mPaint.setStrokeWidth(50);
			mPaint.setStyle(Paint.Style.STROKE);// 描边
			mPaint.setStrokeJoin(Join.ROUND);// 设置路径结合处样式
			mPaint.setStrokeCap(Paint.Cap.ROUND);   // 设置笔触类型  
	
			forgBitmap = Bitmap.createBitmap(sW, sH, Config.ARGB_8888);
			mCanvas = new Canvas(forgBitmap);
			mCanvas.drawColor(0xFF808080);
	
			backgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.tupian);// 背景图
			backgBitmap = Bitmap.createScaledBitmap(backgBitmap, sW, sH, true);
		}
		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			canvas.drawBitmap(backgBitmap, 0, 0, null); // 画背景
			canvas.drawBitmap(forgBitmap, 0, 0, null); // 画前景
			mCanvas.drawPath(mPath, mPaint);
		}
	
		@Override
		public boolean onTouchEvent(MotionEvent event) {
			float x = event.getX();
			float y = event.getY();
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				mPath.reset();
				mPath.moveTo(x, y); //起始点
				preX = x;
				preY = y;
				break;
			case MotionEvent.ACTION_MOVE:
				float dx = Math.abs(x - preX);
				float dy = Math.abs(y - preY);
				if (dx > MOVE_DISTANCE || dy > MOVE_DISTANCE) {
					//赛贝尔曲线
					mPath.quadTo(preX, preY, (x + preX) / 2, (y + preY) / 2);
	//				mPath.quadTo(preX, preY, x, y);
					preX = x;
					preY = y;
				}
				break;
			}
			invalidate();
			return true;
		}
		
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值