android实现画板功能
2015-10-27 23:36
519 查看
上一篇博客实现了android自定义圆形图像这篇博客给大家实现基于xfermode的遮罩层画板功能。首先我会先实现一个简单的画板功能。
ScreenUtil.java
这里我将宽和高封装到了一个整型数组里然后然后返回该数组。
在构造方法中进行初始化:
重写onDraw方法
这里还需要重写onTouchEvent方法,用来根据用户手指的滑动位置,实现mPath具体的绘制工作。
重写onTouchEvent方法
这里在onTouchEvent方法最后返回true表示当前view会消耗掉该事件,如果事件返回false,会将事件再次返回给其父控件来执行。Path可以实现两点之间的平滑过渡。
此时效果如下:
主要增加了如下几步:
首先创建一个和当前屏幕相同大小的mDrawCanvas对象,并且使用颜色将其填充。
为画笔设置Xfermode,也就是以那种方式来显示重叠的部分。
获取需要被隐藏的图片。
先绘制原图像,然后绘制和原图像相同大小的遮罩层
重写onTouchEvent,并且根据mPaint设置的setXfermode来绘制用户滑动的path
onTouchEvent方法是一样的处理方式,这里只是多了一个XferMode的设置。
效果如下:
源码下载
实现简单的画板功能
这里我们的画板是全屏实现的,所以先写一个工具类ScreenUtil来获得屏幕的宽和高的值。ScreenUtil.java
[code]public static int[] getScreenSize(Context context) { int screenSize[] = new int[2]; WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display metrics = windowManager.getDefaultDisplay(); screenSize[0] = metrics.getWidth(); screenSize[1] = metrics.getHeight(); return screenSize; }
这里我将宽和高封装到了一个整型数组里然后然后返回该数组。
新建DrawView类继承自View
这里我们新建一个DrawView extends View ,然后在构造方法里进行初始化,DrawView的属性如下:[code]private Paint mPaint = null; //用于绘制路径的画笔 private Path mPath = null; //用户触摸的路径 private Bitmap desBitmap = null; private Canvas mCanvas = null; private float preX; //上一次的触摸点x坐标 private float preY; //上一次触摸点y坐标 private static final int MIN_SLOP = 5; //最小的滑动距离
在构造方法中进行初始化:
[code]mPath = new Path(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);//设置画笔抗锯齿和抗抖动 mPaint.setStyle(Paint.Style.STROKE); //设置画笔为实心 mPaint.setStrokeCap(Paint.Cap.ROUND); //设置画笔笔触为圆形 mPaint.setStrokeJoin(Paint.Join.ROUND); //设置画笔接触点为圆形 mPaint.setStrokeWidth(30); //画笔的宽度 mPaint.setColor(Color.GREEN); //画笔的颜色 //获取当前屏幕的宽和高 int screenWidth = ScreenUtil.getScreenSize(getContext())[0]; int screenHeight = ScreenUtil.getScreenSize(getContext())[1]; //创建一个BITMAP desBitmap = Bitmap.createBitmap(screenWidth,screenHeight,Config.ARGB_8888); //创建一个和当前bitmap大小相同的画布 mCanvas = new Canvas(desBitmap); //绘制当前画布的填充色 mCanvas.drawColor(Color.parseColor("#cccccc"));
重写onDraw方法
[code]//将desBitmap绘制到当前view的canvas中 canvas.drawBitmap(desBitmap, 0, 0, null); //绘制path,即用户滑动的路径 mCanvas.drawPath(mPath, mPaint);
这里还需要重写onTouchEvent方法,用来根据用户手指的滑动位置,实现mPath具体的绘制工作。
重写onTouchEvent方法
[code]@Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG, "the onTouchEvent runs...."); //获取当前手指相对当前view接触的x,y坐标 /** * 获取当前手指相对当前手机屏幕坐标,接触的x,y坐标 * event.getRawX() * event.getRawY() */ float currentX = event.getX(); float currentY = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d(TAG, "the action_down runs...."); //当用户按下时候,将mPath重置,并且将起始点移动到当前坐标 mPath.reset(); mPath.moveTo(currentX, currentY); //记录上次触摸的坐标,注意ACTION_DOWN方法只会执行一次 preX = currentX; preY = currentY; break; case MotionEvent.ACTION_MOVE: Log.d(TAG, "the action_move runs...."); //ACTION_MOVE方法会多次执行,计算用户水平和垂直方向滑动的距离 int dx = (int) Math.abs(currentX- preX); int dy = (int) Math.abs(currentY - preY); //如果滑动的距离大于规定的值 if (dx > MIN_SLOP || dy > MIN_SLOP) { mPath.quadTo(preX, preY, currentX, currentY); //重新为上一次的触摸点赋值 preX = currentX; preY = currentY; } break; } invalidate();//重新绘制当前view return true; }
这里在onTouchEvent方法最后返回true表示当前view会消耗掉该事件,如果事件返回false,会将事件再次返回给其父控件来执行。Path可以实现两点之间的平滑过渡。
此时效果如下:
使用xfermode实现遮罩层画板
好了,到现在为止我们已经知道如何实现一个基本的画板功能,下面通过结合PorterDuffXfermode来实现遮罩层的画板功能。核心代码如下:[code]private void init() { mPath = new Path(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeWidth(40); mPaint.setColor(Color.argb(20,255,0,0)); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); //获取屏幕的宽高 int screenWidth = ScreenUtil.getScreenSize(getContext())[0]; int screenHeight = ScreenUtil.getScreenSize(getContext())[1]; //创建一个遮罩层,并且使用单独的canvas绘制 mDesBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888); mDrawCanvas = new Canvas(mDesBitmap); mDrawCanvas.drawColor(Color.parseColor("#cccccc")); //获取需要被遮罩的图片并且将其缩放值屏幕大小 mSrcBimap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_back); mSrcBimap = Bitmap.createScaledBitmap(mSrcBimap, screenWidth, screenHeight, false); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); ////先绘制原图像,然后绘制和原图像相同大小的遮罩层 canvas.drawBitmap(mSrcBimap, 0, 0, null); canvas.drawBitmap(mDesBitmap, 0, 0, null); //根据mPaint设置的setXfermode来绘制用户滑动的path mDrawCanvas.drawPath(mPath, mPaint); }
主要增加了如下几步:
首先创建一个和当前屏幕相同大小的mDrawCanvas对象,并且使用颜色将其填充。
[code]/创建一个遮罩层,并且使用单独的canvas绘制 mDesBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888); mDrawCanvas = new Canvas(mDesBitmap); mDrawCanvas.drawColor(Color.parseColor("#cccccc"));
为画笔设置Xfermode,也就是以那种方式来显示重叠的部分。
[code]mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
获取需要被隐藏的图片。
[code]//获取需要被遮罩的图片并且将其缩放值屏幕大小 mSrcBimap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_back); mSrcBimap = Bitmap.createScaledBitmap(mSrcBimap, screenWidth, screenHeight, false);
先绘制原图像,然后绘制和原图像相同大小的遮罩层
[code]canvas.drawBitmap(mSrcBimap, 0, 0, null); canvas.drawBitmap(mDesBitmap, 0, 0, null);
重写onTouchEvent,并且根据mPaint设置的setXfermode来绘制用户滑动的path
[code]mDrawCanvas.drawPath(mPath, mPaint);
onTouchEvent方法是一样的处理方式,这里只是多了一个XferMode的设置。
效果如下:
源码下载
相关文章推荐
- Android线程的基本用法
- Android最小屏幕适配
- 自定义Animation动画,完成跑圈动作
- Unable to start activity com.unionpay.uppay.PayActivity
- 用自定义继承Animation写一个跑圈运动
- 解决android Logcat不显示的问题
- Android问题之PopupWindow GridView onItemClick无效
- android--(联系人提供者实践)
- 关于Android编译中使用的Target Sdk Version,Min Sdk Version和Compile Sdk Version的含义
- Jpush使用总结
- Android EditText 输入完毕 点击空白区域键盘自动退出
- Android手机拍照后照片被旋转或者需要旋转的问题
- Android四大组件之Content Provider(内容提供者)
- Android 中加载几百张图片做帧动画防止 OOM 的解决方案
- android自定义圆形图像
- Android存储-SharedPreferences
- 胖虎谈ImageLoader框架(一)
- 【Android】记录反编译安卓程序步骤
- Android开发之ListView异步加载图片
- Androidstudio 点9图不能识别报错的问题