Reputation: 35
I want to change background color of recycler view row(item) by clicking on it, i use kotlin.
i tried different methods,The item that is clicked changed background color correctly, but when I scroll down I see that another item has also changed background color.
In fact, for every click on the item, another item in the part of the list that is not in the user's view is also affected.
Please explain this problem with a complete example.
Please be sure to test it yourself
I really need to fix this
Thanks a lot
Upvotes: 0
Views: 5074
Reputation: 96
This is mostly because of RecyclerView reuses the view(item row) so that the view need not to be generated multiple times. you can solve the problem by setting the background only for a particular item by changing the value of the the object and for all others keep it default value.
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if(position == selected_item) {
holder.view.setBackgroundColor(Color.parseColor("#00aaff"));
} else {
holder.view.setBackgroundColor(Color.parseColor("#00000")); //actually you should set to the normal text color
}
}
or
public void onItemClick() {
Model model = itemList.get(clickedPosition);
model.setBgColor = Color.parseColor("#00aaff");
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Model model = itemList.get(position);
holder.view.setBackgroundColor(model.getBgColor());
}
Upvotes: 1
Reputation: 1609
it's quite easy to do :) You need to just remember how the RecyclerView works:
So having that in mind, when onBindViewHolder()
is called, the easiest thing you can do is to check some state of the item, and then choose background color of the item. In this scenario you can select/deselect multiple items in the list. If you want to have only one checked, you will need to change the items.map {}
function a little bit:
Please keep in mind that I wrote below from my head, you will also need to override some more functions in adapter etc.
class MyAdapter(private val onItemClick: (YouItem) -> Unit): RecyclerView.Adapter() {
private var items: List<YourItem>
fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val payload = items[holder.adapterPosition]
holder.itemView.setOnClickListener {
onItemClick(payload)
}
holder.itemView.background = if(payload.someState) firstBackground else otherBackground
}
fun updateItems(updatedItems: List<YourItem>) {
items = updatedItems
notifyDataSetChanged()
}
}
class YourActivity: Activity() {
private lateinit var items: List<YourItem>
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
...
items: List<YourItem> = getItemsFromSomewhere()
val adapter = MyAdapter { clickedItem ->
val updatedItems = items.map {
if(it == clickedItem) {
it.copy(someState = !it.someState)
} else {
it
}
items = updatedItems
adapter.updateItems(updatedItems)
}
}
}
data class YourItem(val someState: Boolean)
Upvotes: 3