Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Handle Click Events of Multiple Buttons Inside a RecyclerView

5.00/5 (1 vote)
11 Feb 2018CPOL 40.7K  
Handling multiple click events of multiple buttons placed inside CardView / RecyclerView from Activity instead of from Adapter

Introduction

There are general scenarios where we need to have the button click events be handled inside the Activity instead of an Adapter.

Background

A simple method adding a Listener Interface which is implemented in the Adapter.

Using the Code

Here, using a RecyclerView which holds a CardView and multiple inside CardView. A simple scenario which is picked to explain this is, filtering RecyclerView with List of Trains to be booked in CardViews. Further, the User shall click on Days button (days the train runs) and the Class button (shows another View as per the Class selection). For simplicity and to stick to the topic, only relevant code snippets have been included.

Java
public class TrainBwStnAdapater extends RecyclerView.Adapter<TrainBwStnAdapater.TrainStnViewHolder> {

    //region variables
    private Context mContext;
    private List<TrainDetail> mTrainDetails;
    public DetailsAdapterListener onClickListener;
    //endregion

    //region viewholder class
    public class TrainStnViewHolder extends RecyclerView.ViewHolder  {
    //using ButterKnife for Binding
    //other fields removed for simplicity
        @BindView(R.id.bw_trnNo)
        TextView mTrainNo;
        @BindView(R.id.class_btn)
        AppCompatButton mClassBtn;
        @BindView(R.id.days_btn)
        AppCompatButton mDaysBtn;

        public TrainStnViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);

            mClassBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onClickListener.classOnClick(v, getAdapterPosition());
                }
            });
            mDaysBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onClickListener.daysOnClick(v, getAdapterPosition());
                }
            });
        }
    }
    //endregion

    //region constructor
    public TrainBwStnAdapater(Context context, List<TrainDetail> mTrainDetails, 
                              DetailsAdapterListener listener) {
        this.mContext = context;
        this.mTrainDetails = mTrainDetails;
        this.onClickListener = listener;
    }
    //endregion

    //region overrides
    @Override
    public TrainBwStnAdapater.TrainStnViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.train_bw_stn_card, parent, false);

        return new TrainStnViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(TrainBwStnAdapater.TrainStnViewHolder holder, final int position) {
        TrainDetail trainDetail = mTrainDetails.get(position);
        holder.mTrainNo.setText(String.valueOf(trainDetail.getNumber()));
        //other fields removed for simplicity
    }

    @Override
    public int getItemCount() {
        return mTrainDetails.size();
    }
    //endregion

    //region Interface Details listener
    public interface DetailsAdapterListener {

        void classOnClick(View v, int position);

        void daysOnClick(View v, int position);
    }
    //endregion
}

From the above code snippet, there is an Interface which is supposed to act as the Listener attached with the ClickListener. Also, see the constructor where it takes Listener as one of the parameters.

Calling part or the Activity code snippet is as below:

Java
mTrainDetails = getTrain();
mAdapter = new TrainBwStnAdapater(getBaseContext(), 
           mTrainDetails, new TrainBwStnAdapater.DetailsAdapterListener() {
    @Override
    public void classOnClick(View v, int position) {
        showClass(mTrainDetails, position);// do something or navigate to detailed classes
    }

    @Override
    public void daysOnClick(View v, int position) {
        showDays(mTrainDetails, position);// do something or navigate to running days
    }
});
recyclerView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();

Hope this was kept as simple as possible and was helpful in such common scenarios.

History

  • 12th February, 2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)