Android 多点触控 画板

Android 多点触控 画板_第1张图片

 

 


/**
 * 画板 View
 * 

* Created by zk721 on 2018/2/17. */ public class DrawView extends View { // private private static final String TAG = "DrawView"; /** * 画笔颜色数组 */ private final int[] COLOR_ARRAY = {0xffEA4335, 0xff4285F4, 0xffFBBC05, 0xff34A853, 0xff42BD17, 0xff90BD0E, 0xff18BD8D, 0xff27BDAD, 0xff2098BD, 0xffA96FBD, 0xff86B9BD, 0xff3DBDA4}; /** * 绘制画笔 */ private Paint mPaint = new Paint(); /** * 历史路径 */ private List mDrawMoveHistory = new ArrayList<>(); /** * 用于生成随机数,随机取出颜色数组中的颜色 */ private Random random = new Random(); public DrawView(Context context) { super(context); init(); } public DrawView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public DrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(dip2px(getContext(), 5)); } @Override public boolean onTouchEvent(MotionEvent event) { //多指触控需要使用 getActionMasked switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { //处理点击事件 performClick(); //重置所有 PointerId 为 -1 clearTouchRecordStatus(); //新增一个轨迹 addNewPath(event); //重绘 invalidate(); return true; } case MotionEvent.ACTION_MOVE: { if (mDrawMoveHistory.size() > 0) { for (int i = 0; i < event.getPointerCount(); i++) { //遍历当前屏幕上所有手指 int itemPointerId = event.getPointerId(i);//获取到这个手指的 ID for (DrawPath itemPath : mDrawMoveHistory) { //遍历绘制记录表,通过 ID 找到对应的记录 if (itemPointerId == itemPath.pointerId) { int pointerIndex = event.findPointerIndex(itemPointerId); //通过 pointerIndex 获取到此次滑动事件的所有历史轨迹 List recordList = readPointList(event, pointerIndex); if (!listEquals(recordList, itemPath.record.peek())) { //判断该 List 是否已存在,不存在则添加进去 itemPath.record.push(recordList); addPath(recordList, itemPath.path); } } } } invalidate(); } return true; } case MotionEvent.ACTION_POINTER_UP: //屏幕上有一根指头抬起,但有别的指头未抬起时的事件 int pointerId = event.getPointerId(event.getActionIndex()); for (DrawPath item : mDrawMoveHistory) { if (item.pointerId == pointerId) { //该手指已绘制结束,将此 PointerId 重置为 -1 item.pointerId = -1; } } break; case MotionEvent.ACTION_POINTER_DOWN: //屏幕上已经有了手指,此时又有别的手指点击时事件 addNewPath(event); invalidate(); break; case MotionEvent.ACTION_UP: //最后一根手指抬起,重置所有 PointerId clearTouchRecordStatus(); break; case MotionEvent.ACTION_CANCEL: //事件被取消 clearTouchRecordStatus(); break; } return true; } private void addNewPath(MotionEvent event) { int pointerId = event.getPointerId(event.getActionIndex()); float x = event.getX(event.findPointerIndex(pointerId)); float y = event.getY(event.findPointerIndex(pointerId)); Path path = new Path(); path.moveTo(x, y); path.lineTo(x, y); DrawPath drawPath = new DrawPath(pointerId, getPathColor(), path); List pointList = new ArrayList<>(); pointList.add(new PointF(x, y)); pointList.add(new PointF(x, y)); drawPath.record.push(pointList); mDrawMoveHistory.add(drawPath); } private List readPointList(MotionEvent event, int pointerIndex) { List list = new ArrayList<>(); for (int j = 0; j < event.getHistorySize(); j++) { list.add(new PointF(event.getHistoricalX(pointerIndex, j), event.getHistoricalY(pointerIndex, j))); } return list; } /** * 判断两个列表中所有的数据是否相同 */ private boolean listEquals(List lis1, List list2) { if (lis1.equals(list2)) { return true; } if (lis1.size() != list2.size()) { return false; } if (lis1.isEmpty()) { return true; } for (int i = 0; i < lis1.size(); i++) { PointF point1 = lis1.get(i); PointF point2 = list2.get(i); if (!point1.equals(point2)) { return false; } } return true; } private void addPath(List list, Path path) { for (PointF item : list) { path.lineTo(item.x, item.y); } } /** * 清除记录触摸事件的状态 */ private void clearTouchRecordStatus() { for (DrawPath item : mDrawMoveHistory) { item.pointerId = -1; } } @Override public boolean performClick() { return super.performClick(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mDrawMoveHistory == null || mDrawMoveHistory.isEmpty()) { return; } for (DrawPath item : mDrawMoveHistory) { mPaint.setColor(item.drawColor); canvas.drawPath(item.path, mPaint); } } /** * 清空画布 */ public void clear() { mDrawMoveHistory.clear(); invalidate(); } /** * 获取绘制图案的 Bitmap */ public Bitmap getDrawBitmap() { Bitmap bitmap; try { setDrawingCacheEnabled(true); buildDrawingCache(); bitmap = Bitmap.createBitmap(getDrawingCache(), 0, 0, getMeasuredWidth(), getMeasuredHeight(), null, false); } finally { setDrawingCacheEnabled(false); destroyDrawingCache(); } return bitmap; } /** * 将dip或dp值转换为px值,保证尺寸大小不变 */ private int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) ((double) dipValue * (double) scale + 0.5); } private int getPathColor() { return COLOR_ARRAY[random.nextInt(COLOR_ARRAY.length)]; } private static class DrawPath { /** * 手指 ID,默认为 -1,手指离开后置位 -1 */ private int pointerId = -1; /** * 曲线颜色 */ private int drawColor; /** * 曲线路径 */ private Path path; /** * 轨迹列表,用于判断目标轨迹是否已添加进来 */ private Stack> record; DrawPath(int pointerId, int drawColor, Path path) { this.pointerId = pointerId; this.drawColor = drawColor; this.path = path; record = new Stack<>(); } } }

颜色是可以改滴

 

 

你可能感兴趣的:(Android 多点触控 画板)