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

画不规则图形,当按下的点在图形内拖拽滑动_第1张图片
滑动效果.gif

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


画不规则图形,当按下的点在图形内拖拽滑动_第2张图片
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 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 startPointList;
    private List 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 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 startPointList;
//    private List 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 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 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;
    }
}

你可能感兴趣的:(画不规则图形,当按下的点在图形内拖拽滑动)