ZOFTINO.COM android and web dev tutorials

Android RecyclerView RadioButton

If you need to present list of choices to users and allow them to choose only one option, then RecyclerView with RadiButton is the right choice to implement the feature.

In this post, I’ll show how to use RecyclerView with RadioButton using offers screens of ecommerce application where offers will be displayed in RecyclerView with each offer having a radio button, allows user to select only one offer.

Android RecyclerView RadioButton Example Output

android recyclerview with radiobutton single selection example

Android RecyclerView RadioButton Example Code

The feature of single selection out of multiple options can be implemented using RecyclerView with RadioButton. Following sections explain layout xmls and classes created for implementing the single selection feature, the example displays a screen containing list of offers and radio buttons and it will display message on clicking a radio button.

Item Layout for RecyclerView RadioButton Example

Below item layout contains two text views for displaying offer and offer amount and a radio button.

 <?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/offer_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/offer_amount_txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginBottom="8dp"
        android:layout_marginStart="72dp"
        android:text="Save $ "
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/offer_name" />
    <TextView
        android:id="@+id/offer_amount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.1"
        app:layout_constraintStart_toEndOf="@+id/offer_amount_txt"
        app:layout_constraintTop_toBottomOf="@+id/offer_name" />
    <RadioButton
        android:id="@+id/offer_select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="4dp"
        android:layout_marginStart="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.864"
        app:layout_constraintStart_toEndOf="@+id/offer_name" />
</android.support.constraint.ConstraintLayout>
 

Activity Layout

Activity layout contains title text view and recycler view.

 <?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/offers_title"
        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 One Offer"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <android.support.v7.widget.RecyclerView
        android:id="@+id/offers_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/offers_title"/>
</android.support.constraint.ConstraintLayout>
 

RecyclerView Adapter for RecyclerView with RadioButton Example

RecyclerView adapter populates data in the item layout views from the given list of items. Since RadioButtonGroup can’t be used with recycler view for single selection, we need to implement logic to make sure that only one radio button is selected by clearing previous selection. This logic can be implemented by saving last checked position and using it to uncheck the last checked radio button when user selects different radio button.

 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.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

public class OffersRecyclerViewAdapter extends
        RecyclerView.Adapter<OffersRecyclerViewAdapter.ViewHolder> {

    private List<OffersModel> offersList;
    private Context context;

    private int lastSelectedPosition = -1;

    public OffersRecyclerViewAdapter(List<OffersModel> offersListIn
            , Context ctx) {
        offersList = offersListIn;
        context = ctx;
    }

    @Override
    public OffersRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                                   int viewType) {

        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.offer_item, parent, false);

        OffersRecyclerViewAdapter.ViewHolder viewHolder =
                new OffersRecyclerViewAdapter.ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(OffersRecyclerViewAdapter.ViewHolder holder,
                                 int position) {
        OffersModel offersModel = offersList.get(position);
        holder.offerName.setText(offersModel.getOffer());
        holder.offerAmount.setText("" + offersModel.getSavings());

        //since only one radio button is allowed to be selected,
        // this condition un-checks previous selections
        holder.selectionState.setChecked(lastSelectedPosition == position);
    }

    @Override
    public int getItemCount() {
        return offersList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView offerName;
        public TextView offerAmount;
        public RadioButton selectionState;

        public ViewHolder(View view) {
            super(view);
            offerName = (TextView) view.findViewById(R.id.offer_name);
            offerAmount = (TextView) view.findViewById(R.id.offer_amount);
            selectionState = (RadioButton) view.findViewById(R.id.offer_select);

            selectionState.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    lastSelectedPosition = getAdapterPosition();
                    notifyDataSetChanged();

                    Toast.makeText(OffersRecyclerViewAdapter.this.context,
                            "selected offer is " + offerName.getText(),
                                        Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}
 

Activity

RecyclerView is configured in onCreate method of Activity by setting adapter, layout manager and item decorator.

 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 OffersActivity extends AppCompatActivity {
    private RecyclerView offerRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_filter);

        offerRecyclerView = (RecyclerView) findViewById(R.id.brands_lst);

        LinearLayoutManager recyclerLayoutManager = new LinearLayoutManager(this);
        offerRecyclerView.setLayoutManager(recyclerLayoutManager);

        DividerItemDecoration dividerItemDecoration =
                new DividerItemDecoration(offerRecyclerView.getContext(),
                recyclerLayoutManager.getOrientation());
        offerRecyclerView.addItemDecoration(dividerItemDecoration);


        OffersRecyclerViewAdapter recyclerViewAdapter = new
                OffersRecyclerViewAdapter(getBrands(),this);
        offerRecyclerView.setAdapter(recyclerViewAdapter);
    }

    private List<OffersModel> getBrands(){
        List<OffersModel> modelList = new ArrayList<OffersModel>();
        modelList.add(new OffersModel("Get Upto 20% Off Clothing", 300));
        modelList.add(new OffersModel("Free Smart Phone", 200));
        modelList.add(new OffersModel("Pay $100 get big HD TV", 600));
        modelList.add(new OffersModel("Get Upto 40% Off All", 500));
        modelList.add(new OffersModel("Buy One Get One Free", 100));
        modelList.add(new OffersModel("Pay $200 get Laptop", 1600));
        modelList.add(new OffersModel("Get Upto 50% Off Electronics", 300));
        modelList.add(new OffersModel("Free Movie Ticket", 400));
        modelList.add(new OffersModel("Pay $100 Travel Europe", 700));
        modelList.add(new OffersModel("Get Upto 27% Off Appliance", 600));
        modelList.add(new OffersModel("Get Upto 44% Off Jewellery", 700));
        modelList.add(new OffersModel("Free Coupons", 500));
        modelList.add(new OffersModel("Pay $100 get Tablet", 600));
        return modelList;
    }
}