I’m implementing drag’n’drop for views. When drag is started, I set visibility of the view to INVISIBLE, then, if the drag was interrupted – back to VISIBLE:
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Skipped some code
boolean dragStarted = v.startDrag(data, shadowBuilder, v, 0);
if (dragStarted) {
v.setVisibility(View.INVISIBLE)
}
}
}
And:
if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {
View droppedView = (View) event.getLocalState();
droppedView.setVisibility(View.VISIBLE);
}
And when “Drag ended” event is called, I’m getting exception:
E/AndroidRuntime(7118): FATAL EXCEPTION: main
E/AndroidRuntime(7118): java.util.ConcurrentModificationException
E/AndroidRuntime(7118): at java.util.HashMap$HashIterator.nextEntry(HashMap.java:792)
E/AndroidRuntime(7118): at java.util.HashMap$KeyIterator.next(HashMap.java:819)
E/AndroidRuntime(7118): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1046)
E/AndroidRuntime(7118): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048)
E/AndroidRuntime(7118): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048)
E/AndroidRuntime(7118): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048)
E/AndroidRuntime(7118): at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:3471)
E/AndroidRuntime(7118): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2620)
E/AndroidRuntime(7118): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(7118): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(7118): at android.app.ActivityThread.main(ActivityThread.java:4575)
E/AndroidRuntime(7118): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(7118): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(7118): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
E/AndroidRuntime(7118): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
E/AndroidRuntime(7118): at dalvik.system.NativeStart.main(NativeMethod)
Why and how to fix it?
You can try this
Looks like Android itself trying to access View state at the same time as you end dragging.
EDIT
More precise explanation. By setting
setVisibility(), you’re including or excludingViewfrom Android internal collection of views, that should respond to drag events. This collection is used during dispatch of drag events, and therefore by trying tosetVisibility(in other words, trying to modify listeners of drag events) you’re causingConcurrentModificationException