Drag'n'Drop ConcurentModificationException

南楼画角 提交于 2019-12-23 13:15:53

问题


OnDragListener:

@Override
public boolean onDrag(View v, DragEvent event) {
    switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_ENTERED:
            switch (v.getId()) {
                case R.id.delete_zone: {
                    addToShowCaseZone.setImageDrawable(getResources().getDrawable(R.drawable.showcase_2));
                    inAddToShowcasesZone = true;
                    break;
                }
                case MagazineGridAdapter.ID: {
                    enteredView = v;
                    break;
                }
            }
            return false;

        case DragEvent.ACTION_DRAG_EXITED: {
            switch (v.getId()) {
                case R.id.delete_zone: {
                    addToShowCaseZone.setImageDrawable(getResources().getDrawable(R.drawable.showcase_1));

                    inAddToShowcasesZone = false;
                    break;
                }
                case MagazineGridAdapter.ID: {
                    enteredView = null;
                    break;
                }
            }
            return true;
        }
        case DragEvent.ACTION_DRAG_STARTED:
            return true;

        case DragEvent.ACTION_DRAG_LOCATION:
            return false;

        case DragEvent.ACTION_DROP: {
            if (inAddToShowcasesZone) {
                final int position = gridView.getPositionForView(dragView);

                Magazine magazine = magazineAdapter.getItem(position);

                try {
                    new Magazine(magazine.getUrl().toString(), magazine.getImage(), magazine.getBackgroundNum(), magazine.getName());
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }

                addToShowCaseZone.setImageDrawable(getResources().getDrawable(R.drawable.showcase_1));

                inAddToShowcasesZone = false;

                magazineAdapter.deleteFromList(position);

                return false;

            } else if(enteredView != null && !enteredView.equals(dragView)){
                ResourcesForNativeMagazines.swapItems(gridView.getPositionForView(dragView), gridView.getPositionForView(enteredView), tabNumber - 1);

                magazineAdapter.refreshValues(ResourcesForNativeMagazines.getMagazines(tabNumber - 1));

                enteredView = null;

                return false;
            }

            dragView.setVisibility(VISIBLE);

            return false;
        }
        default:
            dragView.setVisibility(VISIBLE);

            return true;

    }
}

Parts of adapter:

public void refreshValues(List<Magazine> magazines){
    this.magazines = new ArrayList<>(magazines);
    notifyDataSetChanged();
}

public void deleteFromList(int position){
    magazines.remove(position);
    notifyDataSetChanged();
}

Sometimes this code calls error in methods refreshValuews and deleteFromList when i dropped the item, this is stacktrace for it:

java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
        at java.util.HashMap$KeyIterator.next(HashMap.java:833)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1172)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1174)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1174)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1174)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1174)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1174)
        at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1174)
        at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:4911)
        at android.view.ViewRootImpl.access$700(ViewRootImpl.java:94)
        at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3188)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

How i should fix it? Is there any other way to modify items inside gridView by drag'n'drop?


回答1:


I found a solution, not to cause an exception you should do next:

public boolean onDrag(View v, DragEvent event) {
    switch (event.getAction()) {
        case DragEvent.ACTION_DRAG_ENDED:{
            v.post(new Runnable{
                public void run() {
                    //SomeCode;
                }
            });
        break;
        }  
    }
}



回答2:


ConcurrentModification Exception occurs while trying to remove item from the list at the same time when iterating the list.

This can be solved using an Iterator.

This is how you can use an iterator :

Iterator<String> it = myArrayList.iterator();

while (it.hasNext()) {
    String str = it.next();

    if (myCondition)
        it.remove();
}

Refer to the flowing links

How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it?

Java : ConcurrentModificationException while iterating over list



来源:https://stackoverflow.com/questions/25601001/dragndrop-concurentmodificationexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!