android Custom View Circle Drag

  • 2021-12-12 05:54:21
  • OfStack

This article example for everyone to share the android custom View circle drag specific code, for your reference, the specific content is as follows

Question:

1. Accumulation problem: "Click coordinates" coordinates must change their positions when moving, otherwise it will lead to accumulation overload
2. The problem of circle change. The circle will change its position every time it is refreshed
3. Image translation: When the circle moves, it only needs


public class MovingBlockView extends View {

    // Paintbrush 
    Paint paint = new Paint();
    Region circleRegion;
    Path circlePath;
    private boolean Move;

    /* Center of Circle */
    private float x = 300;
    private float y = 300;

    /* Click coordinates */
    private float ClickX = 0;
    private float ClickY = 0;

    /* Moving distance of center of circle */
    private float moveX;
    private float moveY;


    /*
    *  Drag round to question: 
    * 1  . Accumulation problem: "Click coordinates" coordinates must change their positions when moving, otherwise it will lead to accumulation overload 
    *  2.  Circle change problem, the circle will change position every time it is refreshed 
    * 3. Picture translation: When a circle moves, it only needs 
    *
    * */
    public MovingBlockView(Context context) {
        this(context, null);
    }

    public MovingBlockView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MovingBlockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        /*mPaint = new Paint();
        mPaint.setColor(Color.RED);*/

        paint.setColor(Color.RED);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        circlePath = new Path();
        x = x + moveX;
        y = y + moveY;
        circlePath.addCircle(x, y, 300, Path.Direction.CW);
        Region region = new Region(0, 0, getMeasuredWidth(), getMeasuredHeight());
        circleRegion = new Region();
  
        circleRegion.setPath(circlePath, region);

        canvas.drawPath(circlePath, paint);
        canvas.drawLine(x + moveX, 0, x + moveX, getHeight(), paint);
        canvas.drawLine(0, y + moveY, getWidth(), y + moveY, paint);

//        canvas.drawCircle();


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            boolean contains = circleRegion.contains((int) event.getX(), (int) event.getY());
            if (contains) {
//                Toast.makeText(getContext(), " Clicked on the circle ", Toast.LENGTH_LONG).show();
                Move = true;
                ClickX = event.getX();
                ClickY = event.getY();
                Log.d(TAG, "ACTION_DOWN: " + ClickX);
                Log.d(TAG, "ACTION_DOWN: " + ClickY);
            }
        } else if (action == MotionEvent.ACTION_UP) {
            x = x + moveX;
            y = y + moveY;
            Move = false;
            Log.d(TAG, "ACTION_UP: ");
        } else if (action == MotionEvent.ACTION_MOVE) {
            if (Move) {
                Log.d(TAG, "ACTION_MOVE: ");
                moveX = event.getX() - ClickX;
                moveY = event.getY() - ClickY;
                ClickX = event.getX();
                ClickY = event.getY();
                Log.d(TAG, "ACTION_MOVE: " + moveX);
                Log.d(TAG, "ACTION_MOVE: " + moveY);
                invalidate();
            }
        }
        return super.onTouchEvent(event);
    }
}

This site again for you to share a previous favorite code: android custom view round movable


public class Mycircle2 extends View {

    private Paint paint;
    private int rawX;
    private int rawY;
    private int wid;
    private int he;
    int statusBarHeight1 = -1;
    //构造方法,1般会重写3个
    //用于初始化1些数据,或者其他东西
    public Mycircle2(Context context) {
        this(context,null);
    }

    public Mycircle2(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public Mycircle2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //初始化画笔
        //抗锯齿
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置画笔
        paint.setColor(Color.GREEN);//设置画笔颜色
        paint.setStrokeWidth(3);//设置画笔粗细

        //获取整个屏幕的高度和宽度
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        wid = displayMetrics.widthPixels;
        he = displayMetrics.heightPixels;

        //获取status_bar_height资源的ID  获取状态栏的高度
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            statusBarHeight1 = getResources().getDimensionPixelSize(resourceId);
        }
    }
    //重写绘制的方法
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(50,50,50,paint);

      /*  paint.setColor(Color.LTGRAY);
        //实例化路径
        Path path = new Path();
        path.moveTo(80, 200);// 此点为多边形的起点
        path.lineTo(120, 250);
        path.lineTo(80, 250);
        path.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(path, paint);*/
    }

    //拖动事件
    //拖动的实现原理:
/**
 * 每个View在屏幕上都有个坐标,也就是上下左右边距,在屏幕上都有(x,y)坐标。如果坐标移动,那么View的位置也会移动
 * ,这是比较好理解的。
 * 我们手指在手机屏幕上滑动的时候,手指的坐标也是移动的。
 * 我们只需要获得手指从按下到离开过程中的距离差,然后将距离差加到原来的坐标上就可以是实现控件的移动。
 * 如果要实现拖动,那么在滑动的过程中,不断的获取距离差,不断的加到原来的坐标就可以了。
 * 注意:
 *     这里的移动是相对于屏幕的,所以我们获取坐标应该是绝对坐标,而不是相对坐标
 *     event.getRawX() ---- 获取绝对X坐标
 *     event.getRawY() ---- 获取绝对Y坐标
 *
 *     event.getX()-------- 获取相对坐标x
 *     event.getY()-------- 获取相对坐标Y
 *
 */

    // onTouchEvent 处理触摸事件
    //Touch事件:1.按下ACTION_DOWN,2.抬起ACTION_UP,3 滑动 ACTION_MOVE 4.取消ACTION_CANCEL
    //获取触摸点的坐标
    //绝对坐标---相对于屏幕来说
    //相对坐标---相对于自己
    //event.getAction()   获取事件

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //获取开始的坐标
                rawX = (int) event.getRawX();
                rawY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                //获取移动时候的坐标
                int yX = (int) event.getRawX();
                int yY = (int) event.getRawY();
                //减去手指按下时候的坐标
                //得到移动的间距
                int jX=yX-rawX;
                int jY=yY-rawY;
                //将间距,加到原来的坐标(上下左右)
                int l=getLeft()+jX;
                int r=getRight()+jX;
                int t=getTop()+jY;
                int b=getBottom()+jY;

                //判断
                if(l<0){
                    l=0;
                    r=getWidth();
                }
                if(t<0){
                    t=0;
                    b=getHeight();
                }

                if(r>wid){
                    r=wid;
                    l=wid-getHeight();
                }
                //如果移动到最下边,就判断是否等于屏幕高度减去状态栏高度
                if(b>he-statusBarHeight1){
                    //赋值
                    b=he-statusBarHeight1;
                    t=b-getHeight();

                }

                //重新赋值给布局
                layout(l,t,r,b);//规定了View的位置
                //将lastX,lastY重新赋值
                rawX=yX;
                rawY=yY;
                break;
            case  MotionEvent.ACTION_UP:

                break;
        }
        return true;//返回true代表自己处理事件
    }
}

Related articles: