java.util.ConcurrentModificationException в Drag & Drop - PullRequest
0 голосов
/ 24 апреля 2019

Я пытаюсь реализовать поведение перетаскивания в некоторых динамически создаваемых ListViews.Они создаются следующим образом:

private void generateLayout() {
    ArrayList<String> titles=new ArrayList<>();
    titles.add("Taxi");
    titles.add("Minibus");
    for(int i=0;i<vehicles.size();i++){
            HeaderComponent header=new HeaderComponent(ArrivalsListActivity.this);
            header.setText(vehicles.get(i).getVehicleType());
            header.setBackgroundColor(getString(R.color.backcolor));
            ll.addView(header);
            HeaderListComponent hlc=new HeaderListComponent(ArrivalsListActivity.this,vehicles.get(i),titles,null);
            ll.addView(hlc);
            ArrayList<String> passString=new ArrayList<>();
            for(int j=0;j<vehicles.get(i).getPassengers().size();j++){
                passString.add(vehicles.get(i).getPassengers().get(j).getName());
            }
            ListView lv=new ListView(ArrivalsListActivity.this);
            final ArrayAdapter<String> adapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,passString);
            arrayAdapter.add(adapter);
            lv.setAdapter(adapter);
            lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    ClipData data = ClipData.newPlainText("value", adapter.getItem(position));

                    View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
                        view.startDragAndDrop(data,shadowBuilder,adapter.getItem(position),0);
                    }else{
                        view.startDrag(data,shadowBuilder,adapter.getItem(position),0);
                    }

                    return false;
                }
            });
            lv.setOnDragListener(new DragListener(ArrivalsListActivity.this,vehicles.get(i).getPassengers(),almacen));
            ll.addView(lv);
        }
    }
}

Существует два ListView.Я перетаскиваю от первого до второго ListView.

Мой DragListener:

public class DragListener implements View.OnDragListener {

    private Context ctx;
    private ArrayList<PassengerModel> arrayDestino;
    private PassengerModel pasajero;
    private String index;
    private Almacen almacen;

    public DragListener(Context ctx, ArrayList<PassengerModel> destino, Almacen almacen) {
        this.ctx=ctx;
        this.arrayDestino=destino;
        this.almacen=almacen;
    }

    @Override
    public boolean onDrag(View v, DragEvent event) {
        int action = event.getAction();
        ClipDescription desc=event.getClipDescription();
        if(desc!=null){
            index=desc.getLabel().toString();
        }

        switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                if(!dragStarted){
                    almacen.setArrayOrigen(arrayDestino);
                    dragStarted=true;
                }

                // do nothing
                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                break;
            case DragEvent.ACTION_DRAG_EXITED:
                break;
            case DragEvent.ACTION_DROP:
                if(dragStarted){
                    String passenger=(String) event.getLocalState();
                    for(Iterator<PassengerModel> iterator = almacen.getArrayOrigen().iterator(); iterator.hasNext();){
                        PassengerModel pm=iterator.next();
                        if(pm.getName().equals(passenger)){
                            arrayDestino.add(pm);
                            iterator.remove();
                        }
                    }
                    almacen.setArrayDestino(arrayDestino);
                }

                break;
            case DragEvent.ACTION_DRAG_ENDED:
                dragStarted=false;
                generateLayout();
            default:
                break;
        }
        return true;
    }
}

Таким образом, когда выполнение попадает в дело DragEvent.ACTION_DRAG_ENDED, переменная «vehicle» хорошо сформирована, снет PassengerModels в первом и два во втором.

Однако я получаю исключение:

java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(HashMap.java:1441)
    at java.util.HashMap$KeyIterator.next(HashMap.java:1465)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1635)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1637)
    at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:7086)
    at android.view.ViewRootImpl.-wrap12(Unknown Source:0)
    at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:4809)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:7000)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

Почему я получаю это исключение и как его избежать?

Спасибо.

...