If there is a functional requirement in your application that needs list of items to be displayed in UI and allow user to choose multiple items from it, then read this post which explains how to implement the feature using RecyclerView and CheckBox.
You can read RecyclerView, RecyclerView layout manager, RecyclerView item decorator posts to know about RecyclerView.
I’ll take product filter screen of an ecommerce application as an example to show how to implement RecyclerView with CheckBox. The example screen will display list of brands in recycler view with checkbox for each option so that user can select multiple brands from the list.
To add RecyclerView library to your project, first add below entry to module build.gradle file.
compile 'com.android.support:recyclerview-v7:26.0.2'
Below screen shot shows the output of our e-commerce brand filter example.
Following sections provide explanation and code of layouts and classes created for recycler view with checkbox example. When you run below code, screen containing list of brands with options to select items will be shown. On clicking item or on clicking checkbox, it will display message.
First we need to define layout which will be used to display items in RecyclerView. Below layout is defined for our example. It is a constraint layout with two text views to display brand name and product count and check box.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content">
<TextView
android:id="@+id/brand_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="Products"
android:ems="10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/product_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_marginStart="72dp"
android:text="Products"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/brand_name" />
<TextView
android:id="@+id/product_count_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:text="Products"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.18"
app:layout_constraintStart_toEndOf="@+id/product_count"
app:layout_constraintTop_toBottomOf="@+id/brand_name" />
<CheckBox
android:id="@+id/brand_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintBaseline_toBaselineOf="@+id/brand_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.69"
app:layout_constraintStart_toEndOf="@+id/brand_name" />
</android.support.constraint.ConstraintLayout>
For our example, activity layout or screen layout contains TextView for title and RecyclerView.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<TextView
android:id="@+id/filter_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:text="Choose Brands"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/brands_lst"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/filter_txt"/>
</android.support.constraint.ConstraintLayout>
RecyclerView adapter binds data to views in item layout. For each item, item click event listener and checkbox state change listener is added.
package com.example.srinu.stylesthemes;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class ProductFilterRecyclerViewAdapter extends
RecyclerView.Adapter<ProductFilterRecyclerViewAdapter.ViewHolder> {
private List<FilterModel> filterList;
private Context context;
public ProductFilterRecyclerViewAdapter(List<FilterModel> filterModelList
, Context ctx) {
filterList = filterModelList;
context = ctx;
}
@Override
public ProductFilterRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.filter_brand_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
FilterModel filterM = filterList.get(position);
holder.brandName.setText(filterM.getName());
holder.productCount.setText("" + filterM.getProductCount());
if (filterM.isSelected()) {
holder.selectionState.setChecked(true);
} else {
holder.selectionState.setChecked(false);
}
}
@Override
public int getItemCount() {
return filterList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView brandName;
public TextView productCount;
public CheckBox selectionState;
public ViewHolder(View view) {
super(view);
brandName = (TextView) view.findViewById(R.id.brand_name);
productCount = (TextView) view.findViewById(R.id.product_count);
selectionState = (CheckBox) view.findViewById(R.id.brand_select);
//item click event listener
view.setOnClickListener(this);
//checkbox click event handling
selectionState.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
Toast.makeText(ProductFilterRecyclerViewAdapter.this.context,
"selected brand is " + brandName.getText(),
Toast.LENGTH_LONG).show();
} else {
}
}
});
}
@Override
public void onClick(View v) {
TextView brndName = (TextView) v.findViewById(R.id.brand_name);
//show more information about brand
}
}
}
Activity gets data, adds recycler view adapter, recycler view item decorator and recycler view layout manager to recycler view.
package com.example.srinu.stylesthemes;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class BrandsFilterActivity extends AppCompatActivity{
private RecyclerView brandRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
brandRecyclerView = (RecyclerView) findViewById(R.id.brands_lst);
//RecyclerView layout manager
LinearLayoutManager recyclerLayoutManager = new LinearLayoutManager(this);
brandRecyclerView.setLayoutManager(recyclerLayoutManager);
//RecyclerView item decorator
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(brandRecyclerView.getContext(),
recyclerLayoutManager.getOrientation());
brandRecyclerView.addItemDecoration(dividerItemDecoration);
//RecyclerView adapater
ProductFilterRecyclerViewAdapter recyclerViewAdapter = new
ProductFilterRecyclerViewAdapter(getBrands(),this);
brandRecyclerView.setAdapter(recyclerViewAdapter);
}
private List<FilterModel> getBrands(){
List<FilterModel> modelList = new ArrayList<FilterModel>();
modelList.add(new FilterModel("Adidas", 1323, true));
modelList.add(new FilterModel("Nike", 2321, false));
modelList.add(new FilterModel("Reebok", 3221, true));
modelList.add(new FilterModel("Boss", 1323, false));
modelList.add(new FilterModel("Wrangler", 5651, true));
modelList.add(new FilterModel("Lee", 1898, false));
modelList.add(new FilterModel("Levis", 1655, false));
modelList.add(new FilterModel("Polo", 8881, false));
modelList.add(new FilterModel("Tommy Hil", 167, false));
modelList.add(new FilterModel("Nautica", 177, false));
modelList.add(new FilterModel("Gas", 14, false));
modelList.add(new FilterModel("Diesel", 1555, false));
modelList.add(new FilterModel("Gap", 551, false));
modelList.add(new FilterModel("Flying Machine", 199, false));
modelList.add(new FilterModel("Pepe Jeans", 981, true));
modelList.add(new FilterModel("Jack Jones", 561, false));
modelList.add(new FilterModel("Puma", 1832, false));
return modelList;
}
}