11

我有一个自定义 mime 类型,我打算用它在应用程序中拖放应用程序对象。这似乎有效,但我发现 EditText 字段也接受了放置操作。我不希望这种情况发生。

首先,我定义了这样的客户 mime 类型:

public static final String MIME_TYPE_MYNODE = "com.example.mockup/mynode";

然后,在我拥有的源对象的 onTouch 处理程序中:

  @Override
  //-----------------------------------------------------------------------------
  public boolean onTouch (View v, MotionEvent e)
  {
    ...
    else if (e.getAction() == MotionEvent.ACTION_MOVE)
    {
      String[] mimeTypes = {MIME_TYPE_MYNODE};
      ClipData data = new ClipData ("Task Tamer Note", mimeTypes, new ClipData.Item ("unused"));
      View.DragShadowBuilder shadow = new View.DragShadowBuilder(this);
      Object localState = v;
      startDrag (data, shadow, localState, 0);
      return false;
    }
  }
  ...
}

当我在 EditText 小部件上“放置”时,它会将“未使用”插入文本区域。我怎样才能防止这种情况?谢谢。

4

4 回答 4

9

我遇到了同样的行为。我找到了原因,它位于 TextView 类中。

方法 onDragEvent(DragEvent event) 在这里被覆盖,如下所示。

@Override
public boolean onDragEvent(DragEvent event) {
    switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
            return mEditor != null && mEditor.hasInsertionController();

        case DragEvent.ACTION_DRAG_ENTERED:
            TextView.this.requestFocus();
            return true;

        case DragEvent.ACTION_DRAG_LOCATION:
            final int offset = getOffsetForPosition(event.getX(), event.getY());
            Selection.setSelection((Spannable)mText, offset);
            return true;

        case DragEvent.ACTION_DROP:
            if (mEditor != null) mEditor.onDrop(event);
            return true;

        case DragEvent.ACTION_DRAG_ENDED:
        case DragEvent.ACTION_DRAG_EXITED:
        default:
            return true;
    }
}

如果可以插入文本 => EditText,那么任何拖动都将在那里被处理和接受。View 类未使用 OnDragListener,因此无法通过以下方式阻止此行为

editText.setOnDragListener(null);

此处的解决方案是将 EditText 子类化为此处并覆盖 onDragEvent() 方法:

 public class YourEditText extends EditText {

 ...
 // other stuff
 ...

 @Override
 public boolean onDragEvent(DragEvent event) {
    switch (event.getAction()) {
       case DragEvent.ACTION_DRAG_STARTED:
           if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
               return true;
           }
           return false;
       default:
           return super.onDragEvent(event);
    }
}

}

现在 YourEditText 将只接受带有 MIMETYPE_TEXT_PLAIN 的拖动。如果您想完全禁用拖放,只需在此方法中返回 false `

@Override
public boolean onDragEvent(DragEvent event) {
    return false;    
}

就是这样。希望它会有所帮助。

于 2014-03-13T14:36:33.570 回答
3

我遇到了类似的问题,因为我不希望布局接受放置操作。

通过 setOnDragListener 将拖动侦听器附加到您的编辑字段。

edtText.setOnDragListener(new MyDragListener());

检查 onDrag 事件中的目标视图是否是您的编辑文本。

class MyDragListener implements OnDragListener {

    @Override
    public boolean onDrag(View v, DragEvent event) {

      switch (event.getAction()) {
         case DragEvent.ACTION_DROP:
             //check whether it has been dropped onto your edit text
              if(v!=edtText)
                  //your code here
    }
于 2012-09-04T09:23:48.007 回答
1

你可以写

edit.setEnabled(false);
edit.setFocusable(false);

就在调用之后,并在之后恢复该特定控件startDrag()的旧值。editTextDragEvent.ACTION_DRAG_ENDED

但是,老实说,这是一种非常肮脏的方法。

于 2013-09-15T16:13:08.147 回答
1

如果拖动事件成功处理,则返回 true;如果拖动事件未处理,则返回 false。请注意, false 将触发 View 调用其 onDragEvent() 处理程序。

这是 onDrag(View v, DragEvent event) 文档中的声明。因此,如果您返回 false,则事件由 EditText 的 onDragEvent() 处理。因此,最简单的解决方案是:

editText.setOnDragListener(new OnDragListener() {

        @Override
        public boolean onDrag(View v, DragEvent event) {
            return true;
        }
    });

如果您想执行某些功能,请根据 Drag 事件指定它们将被执行。

于 2014-09-27T15:11:41.717 回答