要实现android长按拖拽控件,需要以下因素:
对于控件view,需要以下监听:
1.setOnDragListener()
2.setOnLongClickListener()
给控件view设置长按拖动,以一个imageView为例:
假设一个imageView已经被实例化了。
imageView.setOnLongClickListener(v -> {
View.DragShadowBuilder builder = new View.DragShadowBuilder(v);
v.startDrag(null, builder, null, 0);//第三个参数是传入一个关于这个view信息的任意对象(getLocalState),它即你需要在拖拽监听中的调用event.getLocalState()获取到这个对象来操作用的(比如传入一个RecyclerView中的position)。如果不需要这个对象,传null
return true;
});
假设这个imageView的外围layout对象为containerLayout(比如一个RelativeLayout )
当拖动这个imageView时,外围layout需要执行点什么操作时:
containerLayout.setOnDragListener((v, event) -> {
Log.d("containerLayout", "event.getAction():" + event.getAction());
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_ENDED: //拖拽停止
//your operation
break;
case DragEvent.ACTION_DROP://拖拽中
//your operation
break;
default:
break;
}
return true;
});
当然,不止是外围layout可以做拖拽监听,其他的view也可以针对这个imageView的拖拽行为而做点什么。举个栗子,拖拽这个imageView到另一个view上面时执行点操作:
view1.setOnDragListener(((v, event) -> {
switch (event.getAction()) {
case DragEvent.ACTION_DROP://拖拽中
int index = (int) event.getLocalState();
//之前讲到的v.startDrag(null, builder, null, 0);第三个参数如果传入一个int 类型的值,在这里便可以 通过(int) event.getLocalState()取出来。如果传的是null,上面这行代码就去掉好了
break;
case DragEvent.ACTION_DRAG_ENDED: //拖拽停止
break;
default:
break;
}
return true;
}));
补充:
如果想要长按的瞬间震动一下,可以在长按回调处增加两行代码:
Vibrator vib = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE); //获取系统震动服务
vib.vibrate(70); //震动70毫秒
更详细的对拖拽的各个事件的解释看这个博主的博文即可:
Android 用户界面ImageView拖动复制(Drag and Drop)