使用 FirebaseRecycleradapter 删除项目时 RecyclerView 索引未更新

Ani*_*ena 3 android firebase android-recyclerview firebase-realtime-database

我已经FirebaseRecyclerAdapter为动态 recyclerView实现了,当我试图从列表中删除一个项目时,最初位于错误索引的项目被删除,在删除更多项目后,我得到IndexOutOfBoundsException. 我已经尝试了我找到的所有解决方案,这些解决方案可以看作是在populateViewHolder()方法内部进行了评论。请,如果您必须投反对票,请至少给出正确的答案并投反对票,因为我已经尝试了所有可能的解决方案。下面我发布我的代码。请看一看。

检查delete.setOnClickListener()

     adapter = new FirebaseRecyclerAdapter<Slc, viewHolder>(
                Slc.class,
                R.layout.single_slc_row,
                viewHolder.class,
                FirebaseDatabase.getInstance().getReference().child("DCU")) {
            @Override
            protected void populateViewHolder(final viewHolder viewHolder, final Slc model, final int position)
            {

                //expand collapse
                viewHolder.vis.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v)
                    {
                        // ViewAnimationsUtils.expand(viewHolder.inv);
                        viewHolder.collapse.setVisibility(View.VISIBLE);
                        viewHolder.inv.setVisibility(View.VISIBLE);

                    }
                });
                viewHolder.collapse.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v)
                    {
                        // ViewAnimationsUtils.collapse(inv);
                        viewHolder.inv.setVisibility(View.GONE);
                        viewHolder.collapse.setVisibility(View.GONE);
                    }
                });
                String s=adapter.getRef(position).getKey();
                viewHolder.name.setText(s);

                //dimming get
                viewHolder.dimming.setProgress(model.getPercentage());

                //on off get
                if(model.getON_OFF()==1)
                {
                    viewHolder.onOff.setChecked(true);
                }
                else if(model.getON_OFF()==0)
                {
                    viewHolder.onOff.setChecked(false);
                }

                //dimming set

                //viewHolder.dimming.incrementProgressBy(10);
                viewHolder.showProgress.setText( viewHolder.dimming.getProgress()+"%");
                viewHolder.dimming.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                    @Override
                    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                    {
                        if(position!=RecyclerView.NO_POSITION)
                        {
                            if(seekBar.isShown() && fromUser)
                            {
                                progress= (progress/10)*10;
                                adapter.getRef(position).child("Percentage").setValue(progress);

                                viewHolder.showProgress.setText(progress+"%");
                            }
                        }


                    }

                    @Override
                    public void onStartTrackingTouch(SeekBar seekBar) {

                    }

                    @Override
                    public void onStopTrackingTouch(SeekBar seekBar) {

                    }
                });

                viewHolder.onOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                                                 boolean isChecked) {

                        if(buttonView.isPressed() &&isChecked){
                            adapter.getRef(position).child("ON_OFF").setValue(1);


                        }else{
                            adapter.getRef(position).child("ON_OFF").setValue(0);

                        }

                    }
                });
                viewHolder.delete.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v)
                    {
                        final Dialog dialog = new Dialog(myContext);
                        dialog.setTitle("Delete Slc?");
                        dialog.setContentView(R.layout.delete_slc);
                        dialog.setCancelable(false);
                        Window window = dialog.getWindow();
                        if(window == null) return;
                        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
                        lp.copyFrom(dialog.getWindow().getAttributes());
                        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
                        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
                        lp.gravity = Gravity.CENTER;
                        dialog.getWindow().setAttributes(lp);
                        TextView delete = (TextView)dialog.findViewById(R.id.deleteSlc);
                        final String key= adapter.getRef(position).getKey();
                        delete.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v)
                            {
                               // int pos = viewHolder.getAdapterPosition();

                                ref.child(key).setValue(null);



//                                int selectedItems = position;
//                                for (int i = selectedItems; i >= selectedItems; i--) {
//                                    adapter.getRef(i).removeValue();
                                   adapter.notifyItemRemoved(position);
//                                }
//                                adapter.getRef(position).removeValue();
//
//                                adapter.notifyItemRemoved(position);

                               // adapter.notifyDataSetChanged();

                                dialog.dismiss();
                            }
                        });


                        TextView dialogButton = (TextView) dialog.findViewById(R.id.canceld);
                        // if button is clicked, close the custom dialog
                        dialogButton.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v)
                            {
                                dialog.dismiss();
                            }
                        });

                        dialog.show();

                    }
                });
            }
        };

        slcList.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

删除一些项目后我得到的异常:

  java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
                                                                              at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                              at java.util.ArrayList.get(ArrayList.java:308)
                                                                              at com.firebase.ui.database.FirebaseArray.getItem(FirebaseArray.java:52)
                                                                              at com.firebase.ui.database.FirebaseRecyclerAdapter.getRef(FirebaseRecyclerAdapter.java:150)
Run Code Online (Sandbox Code Playgroud)

koc*_*eng 6

该错误是由于position在函数内部使用了对象而不是直接在populateViewHolder. 就像这个:(但不限于)

protected void populateViewHolder(final viewHolder viewHolder, final Slc model, final int position) {
    // here position object is valid
    ...
    viewHolder.dimming.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged( ... ) {
            // but here, position object is likely to be incorrect
            // especially when you add/remove item of list
        }
        ...
    }
Run Code Online (Sandbox Code Playgroud)

而解决的办法就是把所有position不在直接下的对象都替换populateViewHolderviewHolder.getAdapterPosition().

注意:我从我的评论中复制它以防其他人寻求答案而错过评论