Skip to content

Instantly share code, notes, and snippets.

@jshvarts
Last active January 2, 2021 20:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jshvarts/2fd2adf0c28817aa788fcfa5854220ba to your computer and use it in GitHub Desktop.
Save jshvarts/2fd2adf0c28817aa788fcfa5854220ba to your computer and use it in GitHub Desktop.
// RecyclerView Adapter implemented as ListAdapter and DiffCallback
class Mydapter(
private val clickListener: (String) -> Unit
) :
ListAdapter<MyUiModel, MyViewHolder>(MyDiffCallback()) {
override fun onCreateViewHolder(
parent: ViewGroup,
position: Int
): MyViewHolder {
val binding = MyBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return MyViewHolder(binding, clickListener)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(getItem(position))
}
override fun onBindViewHolder(
holder: MyViewHolder,
position: Int,
payloads: MutableList<Any>
) {
if (payloads.isEmpty()) {
super.onBindViewHolder(holder, position, payloads)
} else {
if (payloads[0] == true) {
holder.bindSelectedState(getItem(position))
}
}
}
}
class MyViewHolder(
private val binding: MyBinding,
private val clickListener: (String) -> Unit
) : RecyclerView.ViewHolder(binding.root), View.OnClickListener {
lateinit var item: MyUiModel
init {
itemView.setOnClickListener(this)
}
fun bind(item: MyUiModel) {
this.item = item
binding.myTextView.text = item.title
Glide.with(binding.myImageView)
.load(item.iconUrl)
.into(binding.myImageView)
}
fun bindSelectedState(item: MyUiModel) {
this.item = item
val itemColor = if (item.isSelected) {
Color.parseColor(item.displayColor)
} else {
Color.WHITE
}
binding.isSelectedIndicator.setBackgroundColor(itemColor)
}
override fun onClick(v: View?) {
v?.let {
clickListener.invoke(item.id)
}
}
}
class MyDiffCallback : DiffUtil.ItemCallback<MyUiModel>() {
override fun areItemsTheSame(
oldItem: MyUiModel,
newItem: MyUiModel
): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(
oldItem: MyUiModel,
newItem: MyUiModel
): Boolean {
return oldItem.isSelected == newItem.isSelected
}
override fun getChangePayload(
oldItem: MyUiModel,
newItem: MyUiModel
): Any? {
return when {
oldItem.isSelected.not() && newItem.isSelected ||
oldItem.isSelected && newItem.isSelected.not() -> true
else -> null
}
}
}
// Fragment using this Adapter:
class MyFragment : Fragment(R.layout.my_fragment) {
private val myAdapter = MyAdapter(this::updateSelectedState)
...
private fun updateSelectedState(categoryId: String) {
val categoryList = myModel.categoryList.value.orEmpty()
categoryList.map { category ->
if (category.id == categoryId) {
category.copy().apply { isSelected = true }
} else category
}.let {
myAdapter.submitList(it)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment