Android RecyclerView : notifyDataSetChanged() IllegalStateException

前端 未结 22 1776
天涯浪人
天涯浪人 2020-11-28 02:57

I\'m trying to update the items of a recycleview using notifyDataSetChanged().

This is my onBindViewHolder() method in the recycleview adapter.

@Over         


        
相关标签:
22条回答
  • 2020-11-28 03:45

    I had the same problem using the Checkbox and the RadioButton. Replacing notifyDataSetChanged() with notifyItemChanged(position) worked. I added a Boolean field isChecked to the data model. Then I updated the Boolean value and in onCheckedChangedListener, I called notifyItemChanged(adapterPosition). This might not be the best way, but worked for me. The boolean value is used for checking whether the item is checked.

    0 讨论(0)
  • 2020-11-28 03:47

    I don't know well, but I also had same problem. I solved this by using onClickListner on checkbox

    viewHolder.mCheckBox.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (model.isCheckboxBoolean()) {
                    model.setCheckboxBoolean(false);
                    viewHolder.mCheckBox.setChecked(false);
                } else {
                    model.setCheckboxBoolean(true);
                    viewHolder.mCheckBox.setChecked(true);
                }
                notifyDataSetChanged();
            }
        });
    

    Try this, this may help!

    0 讨论(0)
  • 2020-11-28 03:48

    Found a simple solution -

    public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    
        private RecyclerView mRecyclerView; 
    
        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            mRecyclerView = recyclerView;
        }
    
        private CompoundButton.OnCheckedChangeListener checkedChangeListener 
        = (compoundButton, b) -> {
            final int position = (int) compoundButton.getTag();
            // This class is used to make changes to child view
            final Event event = mDataset.get(position);
            // Update state of checkbox or some other computation which you require
            event.state = b;
            // we create a runnable and then notify item changed at position, this fix crash
            mRecyclerView.post(new Runnable() {
                @Override public void run() {
                    notifyItemChanged(position));
                }
            });
        }
    }
    

    Here we create a runnable to notifyItemChanged for a position when recyclerview is ready to handle it.

    0 讨论(0)
  • 2020-11-28 03:48

    For me problem occurred when I exited from EditText by Done, Back, or outside input touch. This causes to update model with input text, then refresh recycler view via live data observing.

    The Problem was that cursor/focus remain in EditText.

    When I have deleted focus by using:

    editText.clearFocus() 
    

    Notify data changed method of recycler view did stop throwing this error.

    I think this is one of the possible reason/solutions to this problem. It is possible that this exception can be fixed in another way as it can be caused by totally different reason.

    0 讨论(0)
  • 2020-11-28 03:49

    I ran into this exact issue! After Moonsoo's answer didn't really float my boat, I messed around a bit and found a solution that worked for me.

    First, here's some of my code:

        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
    
        final Event event = mDataset.get(position);
    
        //
        //  .......
        //
    
        holder.mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                event.setActive(isChecked);
                try {
                    notifyItemChanged(position);
                } catch (Exception e) {
                    Log.e("onCheckChanged", e.getMessage());
                }
            }
        });
    

    You'll notice I'm specifically notifying the adapter for the position I'm changing, instead of the entire dataset like you're doing. That being said, although I can't guarantee this will work for you, I resolved the problem by wrapping my notifyItemChanged() call in a try/catch block. This simply caught the exception, but still allowed my adapter to register the state change and update the display!

    Hope this helps someone!

    EDIT: I'll admit, this probably is not the proper/mature way of handle the issue, but since it doesn't appear to be causing any problems by leaving the exception unhandled, I thought I'd share in case it was good enough for someone else.

    0 讨论(0)
  • 2020-11-28 03:49

    simply use isPressed() method of CompoundButton in onCheckedChanged(CompoundButton compoundButton, boolean isChecked)
    e.g

    public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {   
                          ... //your functionality    
                                if(compoundButton.isPressed()){
                                    notifyDataSetChanged();
                                }
                            }  });
    
    0 讨论(0)
提交回复
热议问题