I'm trying to implement a RecyclerView with multiple selectable items.
Here is what I've tried but I couldn't make it work.
This is what I'm trying to do:
Multi Selection in Android RecyclerView For multi selection, we need to add one variable in our POJO (Employee. java) named isChecked as boolean. Now the logic is when user clicks any item of the recyclerview, we just set to true this field.
By default it have 5.
I know it's a little bit late to answer this question. And I don't know whether it meets requirements of OP or not. But this may help someone. I implemented this multi-select RecyclerView with a simple trick. Here is my code.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#EEE"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
item_row.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:background="#FFF" android:clickable="true" android:orientation="vertical"> <TextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" tools:text="TextView" /> </LinearLayout>
In item_row.xml
android:clickable="true"
is important.
MainActivity.java
public class MainActivity extends AppCompatActivity { private List<Model> mModelList; private RecyclerView mRecyclerView; private RecyclerView.Adapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); mAdapter = new RecyclerViewAdapter(getListData()); LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this); mRecyclerView.setHasFixedSize(true); mRecyclerView.setLayoutManager(manager); mRecyclerView.setAdapter(mAdapter); } private List<Model> getListData() { mModelList = new ArrayList<>(); for (int i = 1; i <= 25; i++) { mModelList.add(new Model("TextView " + i)); } return mModelList; } }
Model.java
public class Model { private String text; private boolean isSelected = false; public Model(String text) { this.text = text; } public String getText() { return text; } public void setSelected(boolean selected) { isSelected = selected; } public boolean isSelected() { return isSelected; } }
RecyclerViewAdapter.java
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> { private List<Model> mModelList; public RecyclerViewAdapter(List<Model> modelList) { mModelList = modelList; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { final Model model = mModelList.get(position); holder.textView.setText(model.getText()); holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE); holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { model.setSelected(!model.isSelected()); holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE); } }); } @Override public int getItemCount() { return mModelList == null ? 0 : mModelList.size(); } public class MyViewHolder extends RecyclerView.ViewHolder { private View view; private TextView textView; private MyViewHolder(View itemView) { super(itemView); view = itemView; textView = (TextView) itemView.findViewById(R.id.text_view); } } }
How does it work? onBindViewHolder()
method binds the data from ArrayList to View objects. So, on time binding the data to the view it gets the single object from ArrayList that is Model model = mModelList.get(position);
with the current position. Now we need to check whether that particular object is selected or not. Like this,
model.isSelected()
which returns either true
or false
. If that object is already selected we need to change the background color of row_item
selected. For this here is the code
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
If it's selected change the background color to cyan
else white
.
For selection we need to use setOnClickListener()
method. (here I am using only a TextView
. So I am performing a click event on TextView
). Here holder.view
means the entire single item_row
. Onclick toggle the boolean values to true
or false
.
holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { model.setSelected(!model.isSelected()); holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE); } });
In your Activity or Fragment which is hosting RecyclerView, you can get the selected objects/items like this
String text = ""; for (Model model : mModelList) { if (model.isSelected()) { text += model.getText(); } } Log.d("TAG","Output : " + text);
Here is the output
Edit 1: Restricting user to select only one item.
private int lastSelectedPosition = -1; // declare this variable ... // your code ... @Override public void onBindViewHolder(final MyViewHolder holder, int position) { final Model model = mModelList.get(position); holder.textView.setText(model.getText()); holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE); holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // check whether you selected an item if(lastSelectedPosition > 0) { mModelList.get(lastSelectedPosition).setSelected(false); } model.setSelected(!model.isSelected()); holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE); // store last selected item position lastSelectedPosition = holder.getAdapterPosition(); } }); }
I hope it will be helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With