使用FirebaseRecycleradapter删除项目时,RecyclerView索引不会更新

时间:2017-03-21 09:26:25

标签: android firebase firebase-realtime-database android-recyclerview

我已经为动态recyclelerView实现了FirebaseRecyclerAdapter,当我尝试从列表中删除项目时,最初错误索引的项目将被删除,删除更多项目后,我得到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);

删除某些项目后我得到的例外:

  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)

1 个答案:

答案 0 :(得分:4)

错误是由函数内部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
        }
        ...
    }

解决方案就是将position以外的所有populateViewHolder个对象替换为viewHolder.getAdapterPosition()

  

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