Android自定义View 简单拖拽实现(一)

本篇开始学习自定义View的拖拽实现

先上效果图
在这里插入图片描述

原理

先来说明一下实现原理,这里的核心方法是View.layout(left, top, right, bottom),通过该方法我们可以实现拖拽效果。原理如下:

  1. 我们先获取屏幕触摸点的坐标,然后呢,需要获取控件的四个边框距离坐标原点(0,0)的距离。

  2. 得到这些数据后,然后我们获取移动后的触摸点的坐标,两组触摸点的坐标做差,得到移动的x值和y值。

  3. 最后,我们在四个边距原点的距离之上,加上触摸点差值,就可以得到移动后的控件的四个顶点的位置了。

坐标系

展示一下坐标系,借用参考文档的图片

其中view.getLeft(),view.getTop(),view.getRight(),view.getBottom().是各边距原点的距离,原点在左上角。

控件四边框距离
然后是MotionEvent中的getRawX()、getRawY()和getX()、getY()

getRawX()、getRawY():是触摸点距离原点的距离

getX()、getY():是触摸点距离控件的原点的距离(也就是触摸点到控件左上角的距离)

具体实现

按照上面说明的原理,下面是具体的代码实现

  1. 获取触摸点的坐标
		x = (int) event.getRawX();
        y = (int) event.getRawY();
  1. 获取移动后的坐标,并做差得到移动前后的差值
		int dx = (int) (event.getRawX() - x);
        int dy = (int) (event.getRawY() - y);
  1. 控件移动后的新位置
		// 原来控件四边距原点的距离,加上移动差值,得到新的控件位置
        v.layout(v.getLeft() + dx, v.getTop() + dy, v.getRight() + dx, v.getBottom() + dy);
  1. 把移动后的位置赋值给之前记录边距的变量
		//获取移动后的位置
        x = (int) event.getRawX();
        y = (int) event.getRawY();

以上的代码就是全部的流程了。下面是整体代码,布局就不贴了,就一个TextView。

public class DragTestActivity extends AppCompatActivity {
    
    
    private TextView textView;
    /**
     * 记录触摸点位置的变量
     */
    private int x;
    private int y;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drag_test);
        textView = findViewById(R.id.iv_test);
        textView.setOnTouchListener((v, event) -> {
    
    
            switch (event.getAction()) {
    
    
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_UP:
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int dx = (int) (event.getRawX() - x);
                    int dy = (int) (event.getRawY() - y);
                    // 更改imageView位置,原来View的四边距离
                    v.layout(v.getLeft() + dx, v.getTop() + dy, v.getRight() + dx, v.getBottom() + dy);
                    //获取移动后的位置
                    x = (int) event.getRawX();
                    y = (int) event.getRawY();
                    break;
                default:
                    break;
            }
            return true;
        });
    }
}

之后会不断学习更新完全自定义View
以下是参考文档
清楚说明View坐标

猜你喜欢

转载自blog.csdn.net/A_Intelligence/article/details/110392645