安卓实现View的拖曳有几种方法,都不外乎改变View的坐标,并且重绘,于是,只要能够改变之就可以。
可以自定义View,重写OnTouchEvent(MotionEvent event),可以在Activity 的onTouch()方法中监听手指在屏幕上的位置变化实现,也可以设置View的OnTouch监听。
自定义View的方式:
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
/**
* 自定义的view,能够随意拖动。
*/
public class DragView extends ImageView {
public DragView(Context context) {
super(context);
}
public DragView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public DragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public DragView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private float downX;
private float downY;
private long downTime;
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (this.isEnabled()) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
final float xDistance = event.getX() - downX;
final float yDistance = event.getY() - downY;
if (xDistance != 0 && yDistance != 0) {
int l = (int) (getLeft() + xDistance);
int r = (int) (getRight() + xDistance);
int t = (int) (getTop() + yDistance);
int b = (int) (getBottom() + yDistance);
this.layout(l, t, r, b);
}
break;
case MotionEvent.ACTION_UP:
setPressed(false);
break;
case MotionEvent.ACTION_CANCEL:
setPressed(false);
break;
default:
break;
}
return true;
}
return false;
}
}
通过设置onTouch监听的方式,封装成工具类,方便重用:
import android.view.MotionEvent;
import android.view.View;
/**
* 这个工具可以使任何一个view进行拖动。
*/
public class DragViewUtil {
public static void registerDragAction(View v) {
registerDragAction(v, 0);
}
/**
* 拖动View方法
*
* @param v view
* @param delay 延迟
*/
public static void registerDragAction(View v, long delay) {
v.setOnTouchListener(new TouchListener(delay));
}
private static class TouchListener implements View.OnTouchListener {
private float downX;
private float downY;
private long downTime;
private long delay;
private boolean isMove;
private boolean canDrag;
private TouchListener() {
this(0);
}
private TouchListener(long delay) {
this.delay = delay;
}
private boolean haveDelay() {
return delay > 0;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
isMove = false;
downTime = System.currentTimeMillis();
if (haveDelay()) {
canDrag = false;
} else {
canDrag = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (haveDelay() && !canDrag) {
long currMillis = System.currentTimeMillis();
if (currMillis - downTime >= delay) {
canDrag = true;
}
}
if (!canDrag) {
break;
}
final float xDistance = event.getX() - downX;
final float yDistance = event.getY() - downY;
if (xDistance != 0 && yDistance != 0) {
int l = (int) (v.getLeft() + xDistance);
int r = (int) (l + v.getWidth());
int t = (int) (v.getTop() + yDistance);
int b = (int) (t + v.getHeight());
// v.layout(l, t, r, b);
v.setLeft(l);
v.setTop(t);
v.setRight(r);
v.setBottom(b);
isMove = true;
}
break;
default:
break;
}
return isMove;
}
}
}
调用方法:
DragViewUtil.registerDragAction(textView); //延迟3秒响应拖曳 DragViewUtil.registerDragAction(button,3000);
运行预览: