I know there are no default selection methods in recyclerview class, But I have tried in following way,
public void onBindViewHolder(ViewHolder holder, final
This is how its looks
Inside your Adapter
private int selectedPosition = -1;
And onBindViewHolder
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
if (selectedPosition == position) {
holder.itemView.setSelected(true); //using selector drawable
holder.tvText.setTextColor(ContextCompat.getColor(holder.tvText.getContext(),R.color.white));
} else {
holder.itemView.setSelected(false);
holder.tvText.setTextColor(ContextCompat.getColor(holder.tvText.getContext(),R.color.black));
}
holder.itemView.setOnClickListener(v -> {
if (selectedPosition >= 0)
notifyItemChanged(selectedPosition);
selectedPosition = holder.getAdapterPosition();
notifyItemChanged(selectedPosition);
});
}
Thats it! As you can see i am just Notifying(updating) previous selected item and newly selected item
My Drawable set it as a background for recyclerview child views
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false" android:state_selected="true">
<shape android:shape="rectangle">
<solid android:color="@color/blue" />
</shape>
</item>
This is how the Adapter class looks like :
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHolder>{
Context context;
ArrayList<RouteDetailsFromFirestore> routeDetailsFromFirestoreArrayList_;
public int lastSelectedPosition=-1;
public MyRecyclerViewAdapter(Context context, ArrayList<RouteDetailsFromFirestore> routeDetailsFromFirestoreArrayList)
{
this.context = context;
this.routeDetailsFromFirestoreArrayList_ = routeDetailsFromFirestoreArrayList;
}
@NonNull
@Override
public MyRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
{
// LayoutInflater layoutInflater = LayoutInflater.from(mainActivity_.getBaseContext());
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
View view = layoutInflater.inflate(R.layout.route_details, viewGroup, false);
return new MyRecyclerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final MyRecyclerViewHolder myRecyclerViewHolder, final int i) {
/* This is the part where the appropriate checking and unchecking of radio button happens appropriately */
myRecyclerViewHolder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b) {
if (lastSelectedPosition != -1) {
/* Getting the reference to the previously checked radio button and then unchecking it.lastSelectedPosition has the index of the previously selected radioButton */
//RadioButton rb = (RadioButton) ((MainActivity) context).linearLayoutManager.getChildAt(lastSelectedPosition).findViewById(R.id.rbRadioButton);
RadioButton rb = (RadioButton) ((MainActivity) myRecyclerViewHolder.mRadioButton.getContext()).linearLayoutManager.getChildAt(lastSelectedPosition).findViewById(R.id.rbRadioButton);
rb.setChecked(false);
}
lastSelectedPosition = i;
/* Checking the currently selected radio button */
myRecyclerViewHolder.mRadioButton.setChecked(true);
}
}
});
}
@Override
public int getItemCount() {
return routeDetailsFromFirestoreArrayList_.size();
}
} // End of Adapter Class
Inside MainActivity.java we call the ctor of Adapter class like this. The context passed is of MainActivity to the Adapter ctor :
myRecyclerViewAdapter = new MyRecyclerViewAdapter(MainActivity.this, routeDetailsList);
You need to clear the OnCheckedChangeListener
before setting setChecked()
:
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mRadioButton.setOnCheckedChangeListener(null);
holder.mRadioButton.setChecked(position == mCheckedPosition);
holder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCheckedPosition = position;
notifyDataSetChanged();
}
});
}
This way it won't trigger the java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
error.