I have a custom mime type which I am intending to use to drag and drop application objects within the app. This seems to be working but I\'m finding that the EditText fields ar
You may write
edit.setEnabled(false);
edit.setFocusable(false);
just after calling startDrag()
, and restore old values for that particular editText
control just after DragEvent.ACTION_DRAG_ENDED
.
But, honestly, this is quite dirty approach.
I encountered the same behaviour. I have found the reason, which is located in TextView class.
The method onDragEvent(DragEvent event) is overrriden here and looks as below.
@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;
}
}
If it is possible to insert text => EditText then any drag will be processed and accepted there. The View class is not using OnDragListener, so it is not possible to prevent this behaviour by
editText.setOnDragListener(null);
The solution here is to subclass the EditText as here and override onDragEvent() method:
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);
}
}
}
Now YourEditText will accept only drags with MIMETYPE_TEXT_PLAIN. If you want to disable the drag drop at all just return false in this method`
@Override
public boolean onDragEvent(DragEvent event) {
return false;
}
And that's it. Hope it will help.
I encountered a similar issue in that I did not want a layout to accept the drop action.
Attach a drag listener to your edit field via the setOnDragListener.
edtText.setOnDragListener(new MyDragListener());
Check whether the target view in the onDrag event is your edit text.
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
}
Returns true if the drag event was handled successfully, or false if the drag event was not handled. Note that false will trigger the View to call its onDragEvent() handler.
This is statement from the docs of onDrag(View v, DragEvent event). So if you return false then the event is handled by onDragEvent() of EditText. Hence the simplest solutions is:
editText.setOnDragListener(new OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
return true;
}
});
In case you would like to perform some functions, specify based on the Drag event and they will be executed.