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.
public class TrainBwStnAdapater extends RecyclerView.Adapter<TrainBwStnAdapater.TrainStnViewHolder> {
private Context mContext;
private List<TrainDetail> mTrainDetails;
public DetailsAdapterListener onClickListener;
public class TrainStnViewHolder extends RecyclerView.ViewHolder {
@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());
}
});
}
}
public TrainBwStnAdapater(Context context, List<TrainDetail> mTrainDetails,
DetailsAdapterListener listener) {
this.mContext = context;
this.mTrainDetails = mTrainDetails;
this.onClickListener = listener;
}
@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()));
}
@Override
public int getItemCount() {
return mTrainDetails.size();
}
public interface DetailsAdapterListener {
void classOnClick(View v, int position);
void daysOnClick(View v, int position);
}
}
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:
mTrainDetails = getTrain();
mAdapter = new TrainBwStnAdapater(getBaseContext(),
mTrainDetails, new TrainBwStnAdapater.DetailsAdapterListener() {
@Override
public void classOnClick(View v, int position) {
showClass(mTrainDetails, position);
}
@Override
public void daysOnClick(View v, int position) {
showDays(mTrainDetails, position);
}
});
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