本篇开始学习自定义 View 的拖拽实现
先上效果图
原理
先来说明一下实现原理,这里的核心方法是 View.layout(left, top, right, bottom),通过该方法我们可以实现拖拽效果。原理如下:
-
我们先获取屏幕触摸点的坐标,然后呢,需要获取控件的四个边框距离坐标原点(0,0)的距离。
-
得到这些数据后,然后我们获取移动后的触摸点的坐标,两组触摸点的坐标做差,得到移动的 x 值和 y 值。
-
最后,我们在四个边距原点的距离之上,加上触摸点差值,就可以得到移动后的控件的四个顶点的位置了。
坐标系
展示一下坐标系,借用参考文档的图片
其中 view.getLeft(),view.getTop(),view.getRight(),view.getBottom(). 是各边距原点的距离,原点在左上角。
然后是 MotionEvent 中的 getRawX()、getRawY() 和 getX()、getY()
getRawX()、getRawY():是触摸点距离原点的距离
getX()、getY():是触摸点距离控件的原点的距离(也就是触摸点到控件左上角的距离)
具体实现
按照上面说明的原理,下面是具体的代码实现
- 获取触摸点的坐标
x = (int) event.getRawX();
y = (int) event.getRawY();
复制代码
- 获取移动后的坐标,并做差得到移动前后的差值
int dx = (int) (event.getRawX() - x);
int dy = (int) (event.getRawY() - y);
复制代码
- 控件移动后的新位置
// 原来控件四边距原点的距离,加上移动差值,得到新的控件位置
v.layout(v.getLeft() + dx, v.getTop() + dy, v.getRight() + dx, v.getBottom() + dy);
复制代码
- 把移动后的位置赋值给之前记录边距的变量
//获取移动后的位置
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 ,觉得本文对你有帮助的话,不妨点个赞。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END