Home > Blockchain >  Kotlin Recyclerview change item color onClick
Kotlin Recyclerview change item color onClick

Time:07-03

i have a Recyclerview adapter in Kotlin and when i click it change the color to Red but if i click another item, the previous item still have the Red color. How to make the logic when the item click it will change Red and when click another item it will back to default color and new item become Red.

this is the adapter

class CategoryAdapter(private val onClick: OnClickListener): RecyclerView.Adapter<CategoryAdapter.ViewHolder>() {

private val diffCallBack = object: DiffUtil.ItemCallback<CategoryResponse>(){
    override fun areItemsTheSame(oldItem: CategoryResponse, newItem: CategoryResponse): Boolean {
        return oldItem.id == newItem.id
    }
    override fun areContentsTheSame(oldItem: CategoryResponse, newItem: CategoryResponse): Boolean {
        return oldItem == newItem
    }
}

private val differ = AsyncListDiffer(this,diffCallBack)
fun submitData(value: List<CategoryResponse>?) = differ.submitList(value)

interface OnClickListener {
    fun onClickItem (data: CategoryResponse)
}

inner class ViewHolder(private val binding: ListCategoryHomeBinding): RecyclerView.ViewHolder(binding.root){
    @SuppressLint("SetTextI18n")
    fun bind (data: CategoryResponse){
        binding.tvCategoryHome.text = data.name
        binding.root.setOnClickListener {
            onClick.onClickItem(data)
            binding.tvCategoryHome.setTextColor(Color.RED) <-- this item when i click another item, previous item stay red. i want to make the previous item back to default color
        }
    }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryAdapter.ViewHolder {
    val inflate = LayoutInflater.from(parent.context)
    return ViewHolder(ListCategoryHomeBinding.inflate(inflate,parent,false))
}

override fun onBindViewHolder(holder: CategoryAdapter.ViewHolder, position: Int) {
    val data = differ.currentList[position]
    data.let {
        holder.bind(data)
    }
}

override fun getItemCount(): Int {
    return differ.currentList.size
  }
}

this is the handle on fragment

categoryAdapter = CategoryAdapter(object: CategoryAdapter.OnClickListener{
        override fun onClickItem(position: Int, data: CategoryResponse) {
            val status = "available"
            val search = ""
            viewModel.getProductBuyer(categoryId = data.id.toString(), status = status, search = search)
        }
    })
    binding.rvCategoryHome.adapter = categoryAdapter

   viewModel.showCategory.observe(viewLifecycleOwner){
        categoryAdapter.submitData(it)
    }

CodePudding user response:

You should keep track of the clicked item position and handle the selected item:

  1. Add a field to your data model:

data class CategoryResponse(
    // other fields,
    isSelected: Boolean = false
)

  1. Remove this line:
binding.tvCategoryHome.setTextColor(Color.RED) <-- this item when i click another item, previous item stay red. i want to make the previous item back to default color
  1. Pass the item position witch clicked:
interface OnClickListener {
    fun onClickItem (position: Int, data: CategoryResponse)
}

binding.root.setOnClickListener {
     onClick.onClickItem(adapterPosition, data) // <= don't forget this
}
  1. In your fragment(or activity) handle the click listener:
class Fragment: Fragment {
    val adapter = CategoryAdapter(
        onClick = { position, data ->
            val currentList = adapter.currentList.toMutableList()
            currentList.forEach {
                isSelected = false
            }

            currentList[position].isSelected = true

            adapter.submitList(currentList)
        }
    )
}
  1. Handle the isSelected field in adapter
inner class ViewHolder(private val binding: ListCategoryHomeBinding): RecyclerView.ViewHolder(binding.root){
    @SuppressLint("SetTextI18n")
    fun bind (data: CategoryResponse){
        binding.tvCategoryHome.text = data.name
        if(data.isSelected) {
            binding.tvCategoryHome.setTextColor(Color.RED)
        } else {
            binding.tvCategoryHome.setTextColor(Color.BLACK)
        }
        binding.root.setOnClickListener {
           //....
        }
    }
}

  • Related