防止将自定义mimetype拖放到EditText

时间:2012-08-20 16:32:42

标签: android drag-and-drop android-edittext mime-types

我有一个自定义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小部件时,它会在文本区域中插入“unused”。我怎么能阻止这个? 感谢。

4 个答案:

答案 0 :(得分:8)

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

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

@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;
    }
}

如果可以插入text => 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;    
}

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

答案 1 :(得分:2)

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

通过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
    }

答案 2 :(得分:1)

你可以写

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

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

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

答案 3 :(得分:0)

  

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

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

editText.setOnDragListener(new OnDragListener() {

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

如果您想执行某些功能,请根据Drag事件进行指定,然后执行这些功能。