ZOFTINO.COM android and web dev tutorials

Android RecyclerView Checkbox

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.

Adding RecyclerView Library

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'

RecyclerView with CheckBox Example Output

Below screen shot shows the output of our e-commerce brand filter example.

android recyclerview with checkbox example

RecyclerView with CheckBox Example Code

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.

RecyclerView Item Layout with CheckBox

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>
 

Activity Layout

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

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

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;
    }

}