Similar question have been asked, but i can\'t get any of them work.
What i want is to select item in RecyclerView, change the background of that item view, and stor
First of all, you asked where to put the onClickListener - you should put it in the onBindViewHolder. You can also attach a onClickListener in the ViewHolder class of your item like so:
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
}
As to implementing a single selection behaviour, the answers given here work but calling onNotifyDatasetChanged is bad for performance if you have a lot of items as it rebinds all views from scratch each time.
The link given by Rafiduzzaman Sonnet is a good tutorial to understand a lot of things about setting up RecyclerView, but I think it makes single selection behaviour complicated. I am going to answer comprehensively giving everything one might need to make it work. Here's how I implemented the single selection behaviour:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final YourItemViewHolder itemViewHolder = (YourItemViewHolder) holder;
//This will remember which one was selected
itemViewHolder.getItemSelectionIndicator()
.setSelected(position == mSelectedPosition);
itemViewHolder.getItemWrapperView()
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(mLogTag, "Tapped on " + position);
//This is the previous selection
notifyItemChanged(mSelectedPosition);
itemViewHolder.getItemSelectionIndicator().setSelected(true);
mSelectedPosition = position;
//This is the new selection
notifyItemChanged(position);
}
});
getItemSelectionIndicator()
and getItemWrapperView()
are methods inside the item's ViewHolder that return specific views from the item layout. A ItemWrapperView could be the top most Linear/RelativeLayout that wraps the entire item. Setting a click listener on it will ensure clicks work if user taps anywhere in the item's view.
ItemSelectionIndicator can be a Linear or RelativeLayout that has been set a state list drawable background. This means when it is set as selected, it shows a shape drawable automatically to indicate selection. When it is set as unselected, the drawable will be removed automatically. This is what the indicator view looks like:
<RelativeLayout
android:id="@+id/selection_indicator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/selection_indicator_state_list"/>
This is selection_indicator_state_list.xml in res/drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected background -->
<item android:state_selected="true"
android:drawable="@drawable/item_selection_shape"/>
<!-- Unselected background -->
<item android:state_selected="false"
android:drawable="@color/transparent"/>
</selector>
And this is item_selection_shape.xml in res/drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
//22 is value of transparency, BDBDBD is the color
<solid android:color="#22BDBDBD"/>
<stroke android:width="2dp" android:color="@color/md_blue_600"/>
<corners
android:radius="3dp"/>
</shape>
Make global variable to store position and handle click listener in ViewHolder
. Onclick
of item, change the global position value like
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
globalPosition=getAdapterPosition();
notifyDataSetChanged();
}
});
then in onBindViewHolder
if(postion==globalPosition)
{
//change color like
textview.setTextColor(Color.RED);
}
else
{
//revert back to regular color
textview.setTextColor(Color.WHITE);
}
with this code, the item you clicked get red colored and all other wiil be in white.