lisawray / groupie

Groupie helps you display and manage complex RecyclerView layouts.
MIT License
3.66k stars 293 forks source link

I can't remove more than one item in my GroupAdapter. #437

Open vitorhmsilva opened 1 year ago

vitorhmsilva commented 1 year ago

I have an GroupAdapter that i put an swipe animation to delete the specific item the the user touches, but after the first deleted item, it throws an IllegalArgumentException. When i debugged, i found thet when it calls remove from GroupAdapter, it sets position parameter as -1 as if it couldn't find any element in the adapter group list.

Here is the Fragment code:

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        metodos = new OSMetodos(requireContext(), requireActivity(), codOS);
        adapter = new GroupAdapter<>();

        adcTipoServ = view.findViewById(R.id.adcTipoServico);
        adcTipoServ.setOnClickListener(view1 -> metodos.addService());
        recyclerViewOS = view.findViewById(R.id.recyclerViewOSServ);

        for (ObjetoTipoServicoServicoCompleteWrapper wrapper : oldList) {
            OSServicoItem servico = new OSServicoItem(wrapper, requireContext(), this);
            ExpandableGroup objGroup = new ExpandableGroup(servico, false);
            objGroup.add(new OSServProdBtn(this));
            for (ProdutoServicoWithComodoProduto prod : wrapper.produtoServicoWithComodoProdutos) {
                OSServProdutoItem produtoItem = new OSServProdutoItem(prod, requireContext());
                OSServProdutoDetalhes produtoDetalhes = new OSServProdutoDetalhes(prod, requireContext(), requireActivity(), codOS);
                ExpandableGroup prodGroup = new ExpandableGroup(produtoItem, false);
                prodGroup.add(produtoDetalhes);
                objGroup.add(prodGroup);
            }
            groups.add(objGroup);
        }
        adapter.addAll(groups);

        recyclerViewOS.setLayoutManager(new LinearLayoutManager(requireContext()));
        recyclerViewOS.setAdapter(adapter);
    }

    @Override
    public void onResume() {
        super.onResume();
        oldList.clear();
        adapter.clear();
        groups.clear();
        oldList = repo.getObjetoTipoServicoServicoCompleteWrappers(codOS, "D");
        for (ObjetoTipoServicoServicoCompleteWrapper wrapper : oldList) {
            OSServicoItem servico = new OSServicoItem(wrapper, requireContext(), this);
            ExpandableGroup objGroup = new ExpandableGroup(servico, false);
            objGroup.add(new OSServProdBtn(this));
            for (ProdutoServicoWithComodoProduto prod : wrapper.produtoServicoWithComodoProdutos) {
                OSServProdutoItem produtoItem = new OSServProdutoItem(prod, requireContext());
                OSServProdutoDetalhes produtoDetalhes = new OSServProdutoDetalhes(prod, requireContext(), requireActivity(), codOS);
                ExpandableGroup prodGroup = new ExpandableGroup(produtoItem, false);
                prodGroup.add(produtoDetalhes);
                objGroup.add(prodGroup);
            }
            groups.add(objGroup);
        }
        adapter.addAll(groups);

    }

Here is the onSwipeItem method that deletes the item:

@Override
    public void onSwipeItem(ExpandableGroup group, ObjetoTipoServicoServicoCompleteWrapper wrapper) {
        if (metodos.checkCanUpdate()) {
            SwipeToDelete swipeToDelete = new SwipeToDelete(requireContext()) {
                @Override
                public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
                    if (metodos.checkCanUpdate()) {
                        AlertDialog.Builder alertDialog = new AlertDialog.Builder(requireContext());
                        alertDialog.setTitle("Deletar Objeto?");
                        alertDialog.setMessage("Deseja mesmo deletar esse objeto?");
                        alertDialog.setPositiveButton("Sim", (dialog, which) -> {
                            if (wrapper.objetoTipoServicoServicoEntity.getCdSistemaCriou().equals("W")) {
                                wrapper.objetoTipoServicoServicoEntity.setCdTipoAtualizacao("D");
                                repo.update(wrapper.objetoTipoServicoServicoEntity);
                                for (ProdutoServicoWithComodoProduto produto : wrapper.produtoServicoWithComodoProdutos) {
                                    if (produto.produtoServicoClienteEntity.getCdSistemaCriou().equals("W")) {
                                        produto.produtoServicoClienteEntity.setCdTipoAtualizacao("D");
                                        repo.updateProdutoServicoClienteNew(produto.produtoServicoClienteEntity);
                                        Log.i("BenuERP", "Colocou produto D");
                                    } else {
                                        repo.deleteProdutoServicoClienteNew(produto.produtoServicoClienteEntity);
                                        Log.i("BenuERP", "removeu produto");
                                    }
                                }
                                for (GarantiaServicoClienteNewEntity garantia : wrapper.garantiaServicoClienteNewEntities) {
                                    if (garantia.getCdSistemaCriou().equals("W")) {
                                        garantia.setCdTipoAtualizacao("D");
                                        repo.updateGarantiaServicoClienteNew(garantia);
                                        Log.i("BenuERP", "Colocou garantia D");
                                    } else {
                                        repo.deleteGarantiaServicoClienteNew(garantia);
                                        Log.i("BenuERP", "removeu Garantia");
                                    }
                                }
                                for (FotoObjetoServicoEntity foto : wrapper.fotoObjetoServicoEntities) {
                                    if (foto.getCdSistemaCriou().equals("W")) {
                                        foto.setCdTipoAtualizacao("D");
                                        repo.updateFotoObjetoServico(foto);
                                        Log.i("BenuERP", "Colocou foto D");
                                    } else {
                                        repo.deleteFotoObjetoServico(foto);
                                        Log.i("BenuERP", "removeu Foto");
                                    }
                                }
                                for (EquipamentoObjetoServicoEntity equipamento : wrapper.equipamentoObjetoServicoEntities) {
                                    if (equipamento.getCdSistemaCriou().equals("W")) {
                                        equipamento.setCdTipoAtualizacao("D");
                                        repo.updateEquipamentoObjetoServico(equipamento);
                                        Log.i("BenuERP", "Colocou equipamento D");
                                    } else {
                                        repo.deleteEquipamentoObjetoServico(equipamento);
                                        Log.i("BenuERP", "removeu Equipamento");
                                    }
                                }
                                Log.i("BenuERP", "Colocou Obj D");
                                oldList.remove(wrapper);
                            } else {
                                Log.i("BenuERP", "Removeu obj");
                                repo.delete(wrapper.objetoTipoServicoServicoEntity);
                            }
                            adapter.remove(group);
                            ToastUtils.showConfirmToast(requireContext(), requireActivity(), "Objeto removido com sucesso!");
                            dialog.dismiss();
                        });
                        alertDialog.setNegativeButton("Não", (dialog, which) -> {
                            adapter.notifyDataSetChanged();
                            dialog.dismiss();
                        });
                        alertDialog.show();
                    }
                }
            };
            ItemTouchHelper itemTouchhelper = new ItemTouchHelper(swipeToDelete);
            itemTouchhelper.attachToRecyclerView(recyclerViewOS);
        }
    }

And finally the item class:

public OSServicoItem(ObjetoTipoServicoServicoCompleteWrapper wrapper, Context context, OnSwipe onSwipe) {
        this.wrapper = wrapper;
        this.context = context;
        this.onSwipe = onSwipe;
    }

    @NonNull
    @Override
    protected OsServItemBinding initializeViewBinding(@NonNull View view) {
        return OsServItemBinding.bind(view);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public void bind(@NonNull OsServItemBinding viewBinding, int position) {
        BenuDatabase db = BenuDatabase.getInstance(context);
        TipoServicoDAO dao = db.tipoServicoDAO();
        TipoServicoRepository repo = new TipoServicoImp(dao);
        ObjetoDAO obdao = db.objetoDAO();
        ObjetoRepository obrepo = new ObjetoImp(obdao);
        ObjetoTipoServicoServicoEntity objeto = wrapper.objetoTipoServicoServicoEntity;

        String nmServico = repo.findItemById(objeto.getCdTipoServico()).getNmServico();
        String nmObjeto = obrepo.findItemById(objeto.getCdObjetoTipoServico()).getNmObjeto();

        viewBinding.tvTipoServ.setText(nmServico);
        viewBinding.tvObjServ.setText(nmObjeto);
        viewBinding.getRoot().setOnTouchListener(new GestureHelper(context));
    }

    @Override
    public int getLayout() {
        return R.layout.os_serv_item;
    }

    @Override
    public void setExpandableGroup(@NonNull ExpandableGroup onToggleListener) {
        this.expandableGroup = onToggleListener;
    }

    public class GestureHelper implements View.OnTouchListener {

        private final GestureDetector mGestureDetector;

        public GestureHelper(Context context) {
            mGestureDetector = new GestureDetector(context, new GestureListener(this));
        }

        public void onSwipeRight() {
        }

        public void onSwipeLeft() {
            onSwipe.onSwipeItem(expandableGroup, wrapper);
        }

        public void onSwipeTop() {
        }

        public void onSwipeBottom() {
        }

        public void onDoubleTap() {
        }

        public void onClick() {
            expandableGroup.onToggleExpanded();
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return mGestureDetector.onTouchEvent(event);
        }

        private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;
            private GestureHelper mHelper;

            public GestureListener(GestureHelper helper) {
                mHelper = helper;
            }

            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }

            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                mHelper.onClick();
                return true;
            }

            @Override
            public boolean onDoubleTap(MotionEvent e) {
                mHelper.onDoubleTap();
                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                boolean result = false;
                try {
                    float diffY = e2.getY() - e1.getY();
                    float diffX = e2.getX() - e1.getX();
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffX > 0) {
                                mHelper.onSwipeRight();
                            } else {
                                mHelper.onSwipeLeft();
                            }
                        }
                    } else {
                        if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffY > 0) {
                                mHelper.onSwipeBottom();
                            } else {
                                mHelper.onSwipeTop();
                            }
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                return result;
            }
        }

    }