我在OnDragListener上遇到了一个奇怪的问题。我的目标视图可以很好地获取ACTION_DROP事件并对其进行处理;但它从不接收ACTION_DRAG_STARTED或ACTION_DRAG_ENDED事件(实际上,除了drop之外,它从不接收任何事件)。
这可能是什么原因造成的?这是一个问题,因为当drop发生在目标之外时,我无法处理这种情况。
我找到了this question,但我不清楚答案。任何想法都非常感谢。
我的可拖动视图具有此OnTouchListener
@Override
public boolean onTouch(View v, MotionEvent ev) {
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
startPointX = ev.getX();
startPointY = ev.getY();
isOnClick = true;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (isOnClick) {
isOnClick = false;
// handle single click
}
break;
case MotionEvent.ACTION_MOVE:
if (isOnClick && movePassesThreshold(ev)) {
isOnClick = false;
draggableView.startDrag(...);
}
break;
default:
break;
}
return true;
}目标视图具有以下OnDragListener
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
Log.v(TAG, "drag started");
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DROP:
Log.v(TAG, "drop");
// handle drop
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.v(TAG, "drag ended");
break;
default:
return false;
}
return true;
}发布于 2013-10-19 05:30:25
我的解决方案是这样的:当我的OnTouchListener获得ACTION_UP时,设置一个1秒的延迟runnable,以检查视图是否仍在拖动。如果OnDragListener接收到拖放,则runnable什么也不做;但是如果没有,runnable调用停止拖动以清理并重置视图到它以前的位置。
case MotionEvent.ACTION_UP:
if (isOnClick) {
isOnClick = false;
// handle single click
} else if (draggableView.isDragging()) {
uiHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (draggableView.isDragging()) {
// Drop never got received, so call stopDrag
draggableView.stopDrag();
}
}
}, 1000);
}
break;发布于 2014-11-29 05:55:58
这是ViewGroup的一个已知问题:
https://code.google.com/p/android/issues/detail?id=25073
按照该链接中的建议覆盖dispatchDragEvent函数对我有效:
@Override
public boolean dispatchDragEvent(DragEvent ev){
boolean r = super.dispatchDragEvent(ev);
if (r && (ev.getAction() == DragEvent.ACTION_DRAG_STARTED
|| ev.getAction() == DragEvent.ACTION_DRAG_ENDED)){
// If we got a start or end and the return value is true, our
// onDragEvent wasn't called by ViewGroup.dispatchDragEvent
// So we do it here.
onDragEvent(ev);
}
return r;
}发布于 2013-10-18 03:19:44
这就是我正在做的事情。我不知道它是否会为你工作,但仍在发帖。
@Override
public boolean onTouch(View v, MotionEvent event) {
final ClipData data = ClipData.newPlainText("position",position + "");
v.startDrag(data, pieceDragShadowBuilder, v, 0);
return true;
}然后在我的监听器中它:
@Override
public boolean onDrag(View pV, DragEvent pEvent) {
final int dragAction = pEvent.getAction();
View dragView = (View) pEvent.getLocalState();
final FrameLayout container = (FrameLayout) pV;
if (dragAction == DragEvent.ACTION_DRAG_STARTED)
{
}
else if (dragAction == DragEvent.ACTION_DRAG_ENTERED)
{
}
else if (dragAction == DragEvent.ACTION_DRAG_EXITED)
{
}
else if (dragAction == DragEvent.ACTION_DROP)
{
}现在,我从您的代码中看到的唯一区别是,无论MOVE、UP或CANCEL的具体事件是什么,我都会在onTouch()中调用startDrag()方法。
https://stackoverflow.com/questions/19410949
复制相似问题