我有一个几乎全屏的视图,底部有一个水平的RecyclerView(在自定义视图中)。我正在尝试将元素从RecyclerView拖到页面上半部分的视图上。我正在尝试同时听一下水龙头和拖拽,但大多数时候我无法让触摸监听器返回除ACTION_DOWN和ACTION_CANCEL之外的任何内容。
一个超级讨厌的事情是,如果我放入断点并进入调试模式,它可以正常工作。我得到了ACTION_DOWN - > ACTION_UP - > ACTION_DOWN - > ACTION_UP。有时它也会在第一次启动时起作用,但之后它将无法工作。如果我注释掉v.startDrag()行,它可以很好地工作但是我没有得到阴影。
在onBindViewHolder()中,我为每个项目设置了一个触控监听器,如下所示:
tv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
System.out.println(motionEvent.toString());
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData.Item item = new ClipData.Item(groupId);
String[] clipDescription = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData dragData = new ClipData(groupId), clipDescription, item);
View.DragShadowBuilder shadowBuilder = new DragShadow(v);
v.startDrag(dragData, shadowBuilder, v, 0); //commenting out this line lets me receive actions other than ACTION_CANCEL.
}
return true;
}
});
这是我的DragShadow类。
private class DragShadow extends View.DragShadowBuilder {
View view;
private Point mScaleFactor;
public DragShadow(View view) {
super(view);
this.view = view;
}
@Override
public void onDrawShadow(Canvas canvas) {
canvas.scale(mScaleFactor.x / (float) getView().getWidth(),
mScaleFactor.y / (float) getView().getHeight());
getView().draw(canvas);
}
@Override
public void onProvideShadowMetrics(Point shadowSize,
Point shadowTouchPoint) {
View v = getView();
int height = v.getHeight() * 2;
int width = v.getWidth() * 2;
shadowSize.set(width, height);
mScaleFactor = shadowSize;
shadowTouchPoint.set(width / 2, height / 2);
}
}
如果我添加一个日志语句来立即打印motionEvent作为onTouch中的第一行,它总是ACTION_DOWN,紧接着是ACTION_CANCEL。如果我尝试单击或拖动无关紧要:
07-14 18:39:00.699 11560-11560/com.whis.mobilize I/System.out: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=67.0, y[0]=77.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=109050123, downTime=109050123, deviceId=4, source=0x1002 }
07-14 18:39:00.705 11560-11560/com.whis.mobilize I/System.out: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=277.0, y[0]=1685.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=109050131, downTime=109050123, deviceId=4, source=0x1002 }
07-14 18:39:00.745 11560-11560/com.whis.mobilize I/ViewRootImpl: Reporting drop result: false
07-14 18:39:03.636 11560-11560/com.whis.mobilize I/System.out: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=49.0, y[0]=52.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=109053061, downTime=109053061, deviceId=4, source=0x1002 }
07-14 18:39:03.641 11560-11560/com.whis.mobilize I/System.out: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=439.0, y[0]=1660.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=109053067, downTime=109053061, deviceId=4, source=0x1002 }
07-14 18:39:03.712 11560-11560/com.whis.mobilize I/ViewRootImpl: Reporting drop result: false
我尝试添加添加RecyclerView项侦听器,在任何地方覆盖onTouch(),在任何地方添加requestDisallowInterceptTouchEvent(true),在任何地方覆盖onInterceptTouchEvent(),但没有任何工作。
我在这里发现了其他类似的问题,但都没有答案:
Draggable View not moving, calls ACTION_DOWN then directly to ACTION_CANCEL
EditText only calling ACTION_DOWN and ACTION_CANCEL sometimes
非常感谢任何帮助。谢谢!
修改
我今天早上意识到,当记录上面的触摸事件时,ACTION_CANCEL来自另一个位置。该触摸事件的x和y值与起始ACTION_DOWN的x和y完全不同。我认为它们对应于x和y,其中来自拖动的阴影与活动相对应。我仍然无法修复它。
我刚刚完成并添加了onTouchListeners,它返回false到我可以在整个层次结构中访问的每个视图,这种行为仍在发生。如果我在我的Activity上覆盖dispatchTouchEvent,事件看起来很好,所以它发生在某个嵌套的地方。
我也禁用了所有动画和拉动刷新但没有骰子。
答案 0 :(得分:0)
据我所知,view.startDragAndDrop()
和view.startDrag()
仅应在不同容器/放置区域之间拖动时使用。我认为这就是方法名称更改的原因(因为它们之间没有区别)
如果您只是想拖动ImageView
,则无需使用view.startDragAndDrop()
。为此,您只需执行以下操作即可:
class YourActivity: AppCompatActivity() {
private var imageWidth = 0
private var imageHeight = 0
override fun onCreate(savedInstanceState: Bundle?) {
val imageToMove = findViewById<ImageView>(R.id.your_image)
// get the size of the image, so we can adjust the touch coords later
imageToMove.post {
imageWidth = imageToMove.width
imageHeight = imageToMove.height
}
imageToMove.setOnTouchListener { view, event ->
when (event.action) {
MotionEvent.ACTION_MOVE -> {
// adjust the event coords based on size of the image
//
// the touch coords is the middle of the image, so need
// to account for that
view.x = event.rawX - (pinWidth / 2)
view.y = event.rawY - (pinHeight / 2)
}
}
}
}
}
如果您尝试将视图从一个ViewGroup拖到另一个ViewGroup,则需要使用view.startDragAndDrop()
,然后在需要“拖动上下文感知”的视图上设置拖动侦听器。