Single selection in RecyclerView

后端 未结 15 1110
深忆病人
深忆病人 2020-11-22 15:15

I know there are no default selection methods in recyclerview class, But I have tried in following way,

public void onBindViewHolder(ViewHolder holder, final         


        
15条回答
  •  一向
    一向 (楼主)
    2020-11-22 16:01

    Looks like there are two things at play here:

    (1) The views are reused, so the old listener is still present.

    (2) You are changing the data without notifying the adapter of the change.

    I will address each separately.

    (1) View reuse

    Basically, in onBindViewHolder you are given an already initialized ViewHolder, which already contains a view. That ViewHolder may or may not have been previously bound to some data!

    Note this bit of code right here:

    holder.checkBox.setChecked(fonts.get(position).isSelected());
    

    If the holder has been previously bound, then the checkbox already has a listener for when the checked state changes! That listener is being triggered at this point, which is what was causing your IllegalStateException.

    An easy solution would be to remove the listener before calling setChecked. An elegant solution would require more knowledge of your views - I encourage you to look for a nicer way of handling this.

    (2) Notify the adapter when data changes

    The listener in your code is changing the state of the data without notifying the adapter of any subsequent changes. I don't know how your views are working so this may or may not be an issue. Typically when the state of your data changes, you need to let the adapter know about it.

    RecyclerView.Adapter has many options to choose from, including notifyItemChanged, which tells it that a particular item has changed state. This might be good for your use

    if(isChecked) {
        for (int i = 0; i < fonts.size(); i++) {
            if (i == position) continue;
            Font f = fonts.get(i);
            if (f.isSelected()) {
                f.setSelected(false);
                notifyItemChanged(i); // Tell the adapter this item is updated
            }
        }
        fonts.get(position).setSelected(isChecked);
        notifyItemChanged(position);
    }
    

提交回复
热议问题