Single selection in RecyclerView

后端 未结 15 969
深忆病人
深忆病人 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 15:55

    This might help for those who want a single radiobutton to work --> Radio Button RecycleView - Gist

    If lambda expressions aren't supported, use this instead:

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            notifyItemChanged(mSelectedItem); // to update last selected item.
            mSelectedItem = getAdapterPosition();
        }
    };
    

    Cheers

    0 讨论(0)
  • 2020-11-22 15:55

    So, after spending so many days over this, this is what I came up with which worked for me, and is good practice as well,

    1. Create an interface, name it some listener: SomeSelectedListener.
    2. Add a method which takes an integer:void onSelect(int position);
    3. Initialise the listener in the recycler adapter's constructor as : a) first declare globally as: private SomeSelectedListener listener b) then in constructor initialise as: this.listener = listener;
    4. Inside onClick() of checkbox inside onBindViewHolder(): update the method of the interface/listener by passing the position as: listener.onSelect(position)
    5. In the model, add a variable for deselect say, mSelectedConstant and initialise it there to 0. This represents the default state when nothing is selected.
    6. Add getter and setter for the mSelectedConstant in the same model.
    7. Now, go to your fragment/activity and implement the listener interface. Then override its method: onSelect(int position). Within this method, iterate through your list which you are passing to your adapter using a for loop and setSelectedConstant to 0 for all:

    code

    @Override
    public void onTicketSelect(int position) {
    for (ListType listName : list) {
        listName.setmSelectedConstant(0);
    }
    

    8. Outside this, make the selected position constant 1:

    code

    list.get(position).setmSelectedConstant(1);
    
    1. Notify this change by calling: adapter.notifyDataSetChanged(); immediately after this.
    2. Last step: go back to your adapter and update inside onBindViewHolder() after onClick() add the code to update the checkbox state,

    code

    if (listVarInAdapter.get(position).getmSelectedConstant() == 1) {
        holder.checkIcon.setChecked(true);
        selectedTicketType = dataSetList.get(position);} 
    else {
        commonHolder.checkCircularIcon.setChecked(false);
    }
    
    0 讨论(0)
  • 2020-11-22 15:57

    just use mCheckedPosition save status

    @Override
            public void onBindViewHolder(ViewHolder holder, int position) {
    
                holder.checkBox.setChecked(position == mCheckedPostion);
                holder.checkBox.setOnClickListener(v -> {
                    if (position == mCheckedPostion) {
                        holder.checkBox.setChecked(false);
                        mCheckedPostion = -1;
                    } else {
                        mCheckedPostion = position;
                        notifyDataSetChanged();
                    }
                });
            }
    
    0 讨论(0)
  • 2020-11-22 15:58

    Please try this... This works for me..

    In adapter,take a sparse boolean array.

    SparseBooleanArray sparseBooleanArray;
    

    In constructor initialise this,

       sparseBooleanArray=new SparseBooleanArray();
    

    In bind holder add,

    @Override
    public void onBindViewHolder(DispositionViewHolder holder, final int position) {
       holder.tv_disposition.setText(dispList.get(position).getName());
        if(sparseBooleanArray.get(position,false))
        {
            holder.rd_disp.setChecked(true);
        }
        else
        {
            holder.rd_disp.setChecked(false);
    
    
        }
        setClickListner(holder,position);
    }
    
    private void setClickListner(final DispositionViewHolder holder, final int position) {
        holder.rd_disp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sparseBooleanArray.clear();
                sparseBooleanArray.put(position, true);
                notifyDataSetChanged();
    
    
            }
        });
    }
    

    rd_disp is radio button in xml file.

    So when the recycler view load the items,in bindView Holder it check whether the sparseBooleanArray contain the value "true" correspnding to its position.

    If the value returned is true then we set the radio button selection true.Else we set the selection false. In onclickHolder I have cleared the sparseArray and set the value true corresponding to that position. When I call notify datasetChange it again call the onBindViewHolder and the condition are checked again. This makes our selection to only select particular radio.

    0 讨论(0)
  • 2020-11-22 15:59
                public class GetStudentAdapter extends 
                RecyclerView.Adapter<GetStudentAdapter.MyViewHolder> {
    
                private List<GetStudentModel> getStudentList;
                Context context;
                RecyclerView recyclerView;
    
                public class MyViewHolder extends RecyclerView.ViewHolder {
                    TextView textStudentName;
                    RadioButton rbSelect;
    
                    public MyViewHolder(View view) {
                        super(view);
                        textStudentName = (TextView) view.findViewById(R.id.textStudentName);
                        rbSelect = (RadioButton) view.findViewById(R.id.rbSelect);
                    }
    
    
                }
    
                public GetStudentAdapter(Context context, RecyclerView recyclerView, List<GetStudentModel> getStudentList) {
                    this.getStudentList = getStudentList;
                    this.recyclerView = recyclerView;
                    this.context = context;
                }
    
                @Override
                public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                    View itemView = LayoutInflater.from(parent.getContext())
                            .inflate(R.layout.select_student_list_item, parent, false);
                    return new MyViewHolder(itemView);
                }
    
                @Override
                public void onBindViewHolder(final MyViewHolder holder, final int position) {
                    holder.textStudentName.setText(getStudentList.get(position).getName());
                    holder.rbSelect.setChecked(getStudentList.get(position).isSelected());
                    holder.rbSelect.setTag(position); // This line is important.
                    holder.rbSelect.setOnClickListener(onStateChangedListener(holder.rbSelect, position));
    
                }
    
                @Override
                public int getItemCount() {
                    return getStudentList.size();
                }
                private View.OnClickListener onStateChangedListener(final RadioButton checkBox, final int position) {
                    return new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (checkBox.isChecked()) {
                                for (int i = 0; i < getStudentList.size(); i++) {
    
                                    getStudentList.get(i).setSelected(false);
    
                                }
                                getStudentList.get(position).setSelected(checkBox.isChecked());
    
                                notifyDataSetChanged();
                            } else {
    
                            }
    
                        }
                    };
                }
    
            }
    
    0 讨论(0)
  • 2020-11-22 16:01

    The solution for the issue:

    public class yourRecyclerViewAdapter extends RecyclerView.Adapter<yourRecyclerViewAdapter.yourViewHolder> {
    
    private static CheckBox lastChecked = null;
    private static int lastCheckedPos = 0;
    
    
    public void onBindViewHolder(ViewHolder holder, final int position) {
    
        holder.mTextView.setText(fonts.get(position).getName());
        holder.checkBox.setChecked(fonts.get(position).isSelected());
        holder.checkBox.setTag(new Integer(position));
    
        //for default check in first item
        if(position == 0 && fonts.get(0).isSelected() && holder.checkBox.isChecked())
        {
           lastChecked = holder.checkBox;
           lastCheckedPos = 0;
        }
    
        holder.checkBox.setOnClickListener(new View.OnClickListener() 
        {
            @Override
            public void onClick(View v) 
            {
               CheckBox cb = (CheckBox)v;
               int clickedPos = ((Integer)cb.getTag()).intValue(); 
    
               if(cb.isChecked())
               {
                  if(lastChecked != null)
                  {
                      lastChecked.setChecked(false);
                      fonts.get(lastCheckedPos).setSelected(false);
                  }                       
    
                  lastChecked = cb;
                  lastCheckedPos = clickedPos;
              }
              else
                 lastChecked = null;
    
              fonts.get(clickedPos).setSelected(cb.isChecked);
           }
       });
    }
    }
    

    Hope this help!

    0 讨论(0)
提交回复
热议问题