Android DiffUtil and ListAdapter for RecyclerView list item updates
recyclerview dependency, the minimum support library is 27.
implementation "com.android.support:recyclerview-v7:27.1.0"
ListItem.kt, the data to be displayed in the recyclerview.
data class ListItem(var text : String, var clicks : Int = 0)
ItemArrayAdapter.kt, the implementation of the ListAdapter and DiffUtil for the recyclerview.
import android.support.v7.recyclerview.extensions.ListAdapter
import android.support.v7.util.DiffUtil
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import kotlinx.android.synthetic.main.list_item.view.*
class ItemArrayAdapter(private val listItemClickListener: ListItemClickListener)
: ListAdapter(ListItemCallback()) {
class ListItemCallback : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: ListItem, newItem: ListItem): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: ListItem, newItem: ListItem): Boolean {
return oldItem.text == newItem.text && oldItem.clicks == newItem.clicks
}
}
interface ListItemClickListener {
fun onItemClick(listItem : ListItem, position : Int)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
(holder as ListenItemViewHolder).bind(item, position)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
return ListenItemViewHolder(view)
}
inner class ListenItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tvContent: TextView = itemView.tv_content
var tvClickCount: TextView = itemView.tv_click_counts
fun bind(listItem : ListItem, position : Int) {
tvContent.text = listItem.text
if (listItem.clicks > 0) {
tvClickCount.text = "" + listItem.clicks
} else {
tvClickCount.text = ""
}
itemView.setOnClickListener {
listItemClickListener.onItemClick(listItem, position)
}
Log.d("onclick", "onClick " + position + " " + tvContent.text)
}
}
}
MainActivity.kt, the main activity which initializes the recyclerview. when updating a new list, just call itemArrayAdapter.submitList(itemList)
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
class MainActivity : AppCompatActivity(), ItemArrayAdapter.ListItemClickListener {
private val itemList = ArrayList()
private lateinit var itemArrayAdapter : ItemArrayAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
itemArrayAdapter = ItemArrayAdapter(this)
rv_list.layoutManager = LinearLayoutManager(this)
rv_list.itemAnimator = DefaultItemAnimator()
rv_list.adapter = itemArrayAdapter
(0..99).mapTo(itemList) { ListItem("Item " + it) }
itemArrayAdapter.submitList(itemList)
btn_refresh.setOnClickListener {
val newItemList = ArrayList()
(0..Random().nextInt(100)).mapTo(newItemList) { ListItem("Item ${randomStr()} $it") }
itemArrayAdapter.submitList(newItemList)
}
}
override fun onItemClick(listItem: ListItem, position: Int) {
itemList[position].clicks++
val newItemList = ArrayList()
itemList.forEach {
newItemList.add(ListItem(it.text, it.clicks))
}
itemArrayAdapter.submitList(newItemList)
}
private fun randomStr() : String {
val r = Random()
return java.lang.Long.toString(r.nextLong() and java.lang.Long.MAX_VALUE, 36)
}
}
list_item.xml, the layout for the list item in the recyclerview.
activity_main.xml, the layout for the main activity.
Search within Codexpedia
Custom Search
Search the entire web
Custom Search
Related Posts