可点击的 有边界的 可拖拽控件
有这么一种需求 就是要求控件平时可以点击 然后呢 又可以在屏幕内随意拖拽 然后又不希望控件被拖出屏幕 以屏幕为边界
我们先捋一下思路 然后才能实现一下这个功能 主要功能点就是分为三个部分 我们逐级来实现
第一步 首先要实现可拖拽 这个要通过触摸事件的监听来做处理
第二步 要实现有边界 需要在拖拽过程中 或者在拖拽结束之后 做控件的当前位置判断
第三步 要确定控件在闲时 是可点击的
废话这么多之后 我就直接把最后的实现代码贴上了 (这里说一下 在边界处理上我是在拖拽过程中处理的 如果有人想在拖拽结束后处理也可以 自己把相应的逻辑调一下位置就可以了)
tvButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:// 获取手指第一次接触屏幕
sx = (int) event.getRawX();
sy = (int) event.getRawY();
//layout是整个activity的根控件 你想把view的拖拽空间限制在什么范围 就用哪个控件
screenWidth = layout.getWidth();
screenHeight = layout.getHeight();
break;
case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动对应的事件
int x = (int) event.getRawX();
int y = (int) event.getRawY();
// 获取手指移动的距离
int dx = x - sx;
int dy = y - sy;
// isMove 使用来判断当前控件是否正在被拖拽 用来辅助实现点击空能的 isMove就是一个常量 isMove = false
//这个5也是可以根据自己需求更改精度的
if (Math.abs(dx) > 5 && Math.abs(dy) > 5) {
isMove = true;
}
int left = v.getLeft() + dx;
int top = v.getTop() + dy;
int right = v.getRight() + dx;
int bottom = v.getBottom() + dy;
//这里是给控件设置拖拽边界 开始
if (left < 0) {
left = 0;
right = left + v.getWidth();
}
if (right > screenWidth) {
right = screenWidth;
left = right - v.getWidth();
}
if (top < 0) {
top = 0;
bottom = top + v.getHeight();
}
if (bottom > screenHeight) {
bottom = screenHeight;
top = bottom - v.getHeight();
}
//这里是给控件设置拖拽边界 结束
// 更改imageView在窗体的位置
v.layout(left, top, right, bottom);
// 获取移动后的位置
sx = (int) event.getRawX();
sy = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:// 手指离开屏幕对应事件
//是否实现点击事件 根据isMove标签 在这里做处理
if (isMove) {
// TODO: 2019/10/18 想要在拖拽之后设置边界的 可以在这里写上面的逻辑
isMove = false;
int lastX = (int) event.getRawX();
int lastY = (int) event.getRawY();
return true;
} else {
finish();
}
break;
}
return true;
}
});
}