Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single selection in RecyclerView

I know there are no default selection methods in the RecyclerView class, but I have tried in the following way:

public void onBindViewHolder(ViewHolder holder, final int position) {     holder.mTextView.setText(fonts.get(position).getName());     holder.checkBox.setChecked(fonts.get(position).isSelected());      holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {         @Override         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {             if(isChecked) {                 for (int i = 0; i < fonts.size(); i++) {                     fonts.get(i).setSelected(false);                 }                 fonts.get(position).setSelected(isChecked);             }         }     }); } 

While trying this code, I got the expected output, but not completely.

I will explain this with images.

By default, the first item is selected from my adapter.

Then I select the 2nd, then the 3rd, then the 4th and finally the 5th one.

Here only the 5th should be selected, but all five are getting selected.

If I scroll the list to the bottom and come again to the top, I get what I expect.

How can I overcome this issue? And sometimes if I scroll the list very fast, some other item gets selected. How can I overcome this problem too?

While I was trying to use notifyDataSetChanged() after fonts.get(position).setSelected(isChecked);, I got the following exception:

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling         at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:1462)         at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:2982)         at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:7493)         at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:4338)         at com.app.myapp.screens.RecycleAdapter.onRowSelect(RecycleAdapter.java:111) 
like image 431
Gunaseelan Avatar asked Mar 10 '15 19:03

Gunaseelan


People also ask

How to make single selection in RecyclerView Android?

For single selection, we just need to hold the position that clicked in the recyclerview. When user clicks the another position, forget previous one and make new position as hold position.

What is RecyclerView selection?

List UI is a very common thing in Android Applications. Pretty much every single app has a list of something they want to display. RecyclerView Selection is a library that will allow you to handle item selection a lot easier.


1 Answers

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);            }        });     } } 
like image 92
Xcihnegn Avatar answered Oct 14 '22 08:10

Xcihnegn