首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OnDragListener未收到DRAG_STARTED或DRAG_ENDED,但收到了ACTION_DROP

OnDragListener未收到DRAG_STARTED或DRAG_ENDED,但收到了ACTION_DROP
EN

Stack Overflow用户
提问于 2013-10-17 02:25:42
回答 3查看 10.3K关注 0票数 7

我在OnDragListener上遇到了一个奇怪的问题。我的目标视图可以很好地获取ACTION_DROP事件并对其进行处理;但它从不接收ACTION_DRAG_STARTEDACTION_DRAG_ENDED事件(实际上,除了drop之外,它从不接收任何事件)。

这可能是什么原因造成的?这是一个问题,因为当drop发生在目标之外时,我无法处理这种情况。

我找到了this question,但我不清楚答案。任何想法都非常感谢。

我的可拖动视图具有此OnTouchListener

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-19 05:30:25

我的解决方案是这样的:当我的OnTouchListener获得ACTION_UP时,设置一个1秒的延迟runnable,以检查视图是否仍在拖动。如果OnDragListener接收到拖放,则runnable什么也不做;但是如果没有,runnable调用停止拖动以清理并重置视图到它以前的位置。

代码语言:javascript
复制
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;
票数 2
EN

Stack Overflow用户

发布于 2014-11-29 05:55:58

这是ViewGroup的一个已知问题:

https://code.google.com/p/android/issues/detail?id=25073

按照该链接中的建议覆盖dispatchDragEvent函数对我有效:

代码语言:javascript
复制
@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;
}
票数 6
EN

Stack Overflow用户

发布于 2013-10-18 03:19:44

这就是我正在做的事情。我不知道它是否会为你工作,但仍在发帖。

代码语言:javascript
复制
@Override
public boolean onTouch(View v, MotionEvent event) {
         final ClipData data = ClipData.newPlainText("position",position + "");
         v.startDrag(data, pieceDragShadowBuilder, v, 0);
         return true;
}

然后在我的监听器中它:

代码语言:javascript
复制
                @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()方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19410949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档