美文网首页
画不规则图形,当按下的点在图形内拖拽滑动

画不规则图形,当按下的点在图形内拖拽滑动

作者: 墨色尘埃 | 来源:发表于2017-07-19 09:37 被阅读0次
    滑动效果.gif

    第一种是很顺滑的,在onTouchEvent的ACTION_MOVE事件中也作了重绘的过程,第二种并没有。还有一种情况,在ACTION_MOVE事件中作了监听但是滑动的时候滑的很快,是错误的。


    TIM图片20170719090048.jpg

    当滑动到②点时,偏移量dx=①点坐标+②点坐标
    当滑动到③点时,偏移量dx=①点坐标+③点坐标
    ........
    当滑动到N点时,偏移量dx=①点坐标-N点坐标
    由此看出,不管移动到了哪个点,偏移量都是相对于第一次按下的那个点,即ACTION_DOWN中的点坐标。所以在ACTION_MOVE中,需要实时改变图形的几个坐标点,移到①点就将(最初的图形坐标+偏移量=新坐标)赋值给新坐标,②点再次将(最初的图形坐标+偏移量=新坐标)赋值给新坐标.........一直到N点。因为是连续的过程所以看起来就是一连贯的动作,图形也就跟着自然滑动。重绘的时候一定是重绘新坐标(curPtList)而不是最原始的坐标(startPointList)。程序刚运行的时候curPtList和startPointList相同所以第一次绘制是没有问题的。当松开鼠标的时候,ACTION_UP中将最后移动后确定下来的坐标赋给原始坐标startPointList,再滑动的时候重复上面的过程。其实ACTION_UP的作用只是重新赋值给原始坐标,刷新界面所需的坐标点其实是ACTION_MOVE中最后一次移动后所提供的。

    之所以会出现滑动会出现上面所说的第三种情况就是因为这个原因,偏移量相对于按下的点,但是改变原始坐标startPointList并每次重新赋值导致移到②点时,再改变startPointList(其实这个时候已经是移到①点后改变了的坐标),再次改变就增加了上一次的偏移量导致会偏远。
    ACTION_MOVE中使用这个方法是错误的

    List<Point> newPointList = new ArrayList<>();
                    for (Point point : startPointList) {
                        float newX = point.getX() + dx;
                        float newY = point.getY() + dy;
                        Point newPoint = new Point(newX, newY);
                        newPointList.add(newPoint);
                    }
                    startPointList.clear();
                    startPointList.addAll(newPointList);
    

    完整正确代码

    /**
     * Created by HASEE on 2017/7/18 12:27
     */
    
    public class DrawTestView extends View {
    
        private List<Point> startPointList;
        private List<Point> curPtList;
    
        private Paint paint;
        private Canvas cacheCanvas;
        private Bitmap cachebBitmap;
        private Path path;
        Region re = new Region();
    
        public DrawTestView(Context context) {
            super(context);
            init();
        }
    
        public DrawTestView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public DrawTestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        public void initData() {
            startPointList = new ArrayList<>();
            startPointList.add(new Point(50, 50));
            startPointList.add(new Point(100, 50));
            startPointList.add(new Point(100, 100));
            startPointList.add(new Point(200, 100));
            startPointList.add(new Point(200, 300));
            startPointList.add(new Point(50, 300));
    
            curPtList = new ArrayList<>();
    
            for (Point point : startPointList) {
                curPtList.add(new Point(point.getX(), point.getY()));
            }
        }
    
    
        public void init() {
            initData();
            paint = new Paint();
            paint.setAntiAlias(true);
            paint.setStrokeWidth(4);
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(Color.RED);
    
            cachebBitmap = Bitmap.createBitmap(800, 800, Bitmap.Config.ARGB_8888);
            cacheCanvas = new Canvas(cachebBitmap);
            cacheCanvas.drawColor(Color.CYAN);
    
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            path = new Path();
            path.moveTo(curPtList.get(0).getX(), curPtList.get(0).getY());
            for (int i = 1; i < curPtList.size(); i++) {
                Point point = curPtList.get(i);
                path.lineTo(point.getX(), point.getY());
            }
            path.close();
            canvas.drawBitmap(cachebBitmap, 0, 0, null);
            canvas.drawPath(path, paint);
    
    
        }
    
        private float cur_x, cur_y;
        private boolean isMoving;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    cur_x = x;
                    cur_y = y;
                    Log.e("DrawTestView", "DOWN" + cur_x + "/" + cur_y);
                    //构造一个区域对象,左闭右开的。
                    RectF r = new RectF();
                    //计算控制点的边界
                    path.computeBounds(r, true);
                    //设置区域路径和剪辑描述的区域
                    re.setPath(path, new Region((int) r.left, (int) r.top, (int) r.right, (int) r.bottom));
                    //在封闭的path内返回true 不在返回false
                    isMoving = re.contains((int) event.getX(), (int) event.getY());
                    Log.e("DrawTestView", "--判断点是否则范围内----" + isMoving);
    
                    break;
                }
    
                case MotionEvent.ACTION_MOVE: {
                    Log.e("DrawTestView", "MOVE");
    
                    if (!isMoving)
                        break;  //return
    
                    path.reset();
                    path.moveTo(x, y);
                    float dx = x - cur_x;
                    float dy = y - cur_y;
                    Log.e("DrawTestView", "UP" + dx + "/" + dy);
    
                    for (int i = 0; i < curPtList.size(); i++) {
                        curPtList.get(i).setX(startPointList.get(i).getX() + dx);
                        curPtList.get(i).setY(startPointList.get(i).getY() + dy);
                    }
    
                    break;
                }
    
                case MotionEvent.ACTION_UP: {
                    if (!isMoving)
                        break;  //return
    //                path.reset();
    //                path.moveTo(x, y);
                    float dx = x - cur_x;
                    float dy = y - cur_y;
                    Log.e("DrawTestView", "UP" + dx + "/" + dy);
    
                    List<Point> newPointList = new ArrayList<>();
                    for (Point point : startPointList) {
                        float newX = point.getX() + dx;
                        float newY = point.getY() + dy;
                        Point newPoint = new Point(newX, newY);
                        newPointList.add(newPoint);
                    }
                    startPointList.clear();
                    startPointList.addAll(newPointList);
                    break;
                }
            }
    
            // 通知刷新界面
            invalidate();
            return true;
        }
    }
    

    第三种情况下的代码

    /**
     * Created by HASEE on 2017/7/18 12:27
     */
    
    public class DrawTestView1 extends View {
    
        private List<Point> startPointList;
    //    private List<Point> curPtList;
    
        private Paint paint;
        private Canvas cacheCanvas;
        private Bitmap cachebBitmap;
        private Path path;
        Region re = new Region();
    
        public DrawTestView1(Context context) {
            super(context);
            init();
        }
    
        public DrawTestView1(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public DrawTestView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        public void initData() {
            startPointList = new ArrayList<>();
            startPointList.add(new Point(50, 50));
            startPointList.add(new Point(100, 50));
            startPointList.add(new Point(100, 100));
            startPointList.add(new Point(200, 100));
            startPointList.add(new Point(200, 300));
            startPointList.add(new Point(50, 300));
    //
    //        curPtList = new ArrayList<>();
    //
    //        for (Point point : startPointList) {
    //            curPtList.add(new Point(point.getX(), point.getY()));
    //        }
        }
    
    
        public void init() {
            initData();
            paint = new Paint();
            paint.setAntiAlias(true);
            paint.setStrokeWidth(4);
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(Color.RED);
    
            cachebBitmap = Bitmap.createBitmap(800, 800, Bitmap.Config.ARGB_8888);
            cacheCanvas = new Canvas(cachebBitmap);
            cacheCanvas.drawColor(Color.CYAN);
    
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            path = new Path();
            path.moveTo(startPointList.get(0).getX(), startPointList.get(0).getY());
            for (int i = 1; i < startPointList.size(); i++) {
                Point point = startPointList.get(i);
                path.lineTo(point.getX(), point.getY());
            }
    //        path.moveTo(curPtList.get(0).getX(), curPtList.get(0).getY());
    //        for (int i = 1; i < curPtList.size(); i++) {
    //            Point point = curPtList.get(i);
    //            path.lineTo(point.getX(), point.getY());
    //        }
            path.close();
            canvas.drawBitmap(cachebBitmap, 0, 0, null);
            canvas.drawPath(path, paint);
    
    
        }
    
        private float cur_x, cur_y;
        private boolean isMoving;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    cur_x = x;
                    cur_y = y;
                    Log.e("DrawTestView", "DOWN" + cur_x + "/" + cur_y);
                    //构造一个区域对象,左闭右开的。
                    RectF r = new RectF();
                    //计算控制点的边界
                    path.computeBounds(r, true);
                    //设置区域路径和剪辑描述的区域
                    re.setPath(path, new Region((int) r.left, (int) r.top, (int) r.right, (int) r.bottom));
                    //在封闭的path内返回true 不在返回false
                    isMoving = re.contains((int) event.getX(), (int) event.getY());
                    Log.e("DrawTestView", "--判断点是否则范围内----" + isMoving);
    
                    break;
                }
    
                case MotionEvent.ACTION_MOVE: {
                    Log.e("DrawTestView", "MOVE");
    
                    if (!isMoving)
                        break;  //return
    
                    path.reset();
                    path.moveTo(x, y);
                    float dx = x - cur_x;
                    float dy = y - cur_y;
                    Log.e("DrawTestView", "UP" + dx + "/" + dy);
    
    //                for (int i = 0; i < curPtList.size(); i++) {
    //                    curPtList.get(i).setX(startPointList.get(i).getX() + dx);
    //                    curPtList.get(i).setY(startPointList.get(i).getY() + dy);
    //                }
    
                    List<Point> newPointList = new ArrayList<>();
                    for (Point point : startPointList) {
                        float newX = point.getX() + dx;
                        float newY = point.getY() + dy;
                        Point newPoint = new Point(newX, newY);
                        newPointList.add(newPoint);
                    }
                    startPointList.clear();
                    startPointList.addAll(newPointList);
    
                    break;
                }
    
                case MotionEvent.ACTION_UP: {
                    if (!isMoving)
                        break;  //return
                    float dx = x - cur_x;
                    float dy = y - cur_y;
                    Log.e("DrawTestView", "UP" + dx + "/" + dy);
    
                    List<Point> newPointList = new ArrayList<>();
                    for (Point point : startPointList) {
                        float newX = point.getX() + dx;
                        float newY = point.getY() + dy;
                        Point newPoint = new Point(newX, newY);
                        newPointList.add(newPoint);
                    }
                    startPointList.clear();
                    startPointList.addAll(newPointList);
                    break;
                }
            }
    
            // 通知刷新界面
            invalidate();
            return true;
        }
    }
    

    相关文章

      网友评论

          本文标题:画不规则图形,当按下的点在图形内拖拽滑动

          本文链接:https://www.haomeiwen.com/subject/rlwkkxtx.html