notifyDataSetChanged()보다 더 효율적으로 작업하기 위한 DiffUtil() 클래스.
DiffCallback.kt
inner class DiffCallback(
private var oldList: ArrayList<RecyclerViewItem>,
private var newList: ArrayList<RecyclerViewItem>
): DiffUtil.Callback() {
override fun getOldListSize(): Int = oldList.size
override fun getNewListSize(): Int = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].id == newList[newItemPosition].id
}
RecyclerViewAdapter.kt 에서 setData라는 함수를 통해 diffUtil 사용
package com.mj.recyclerview_sample
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
class RecyclerViewAdapter(): RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
return RecyclerViewViewHolder(itemView)
}
override fun onBindViewHolder(holder: RecyclerViewViewHolder, position: Int) {
holder.bind(recyclerViewItems[position])
}
override fun getItemCount(): Int {
return recyclerViewItems.size
}
fun setData(newRecyclerViewItems: ArrayList<RecyclerViewItem>){
println(newRecyclerViewItems.size)
val diffCallback = DiffCallback(recyclerViewItems, newRecyclerViewItems)
val diffResult = DiffUtil.calculateDiff(diffCallback)
recyclerViewItems.clear()
println(newRecyclerViewItems.size)
recyclerViewItems.addAll(newRecyclerViewItems)
diffResult.dispatchUpdatesTo(this)
}
inner class RecyclerViewViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
private val title: TextView = itemView.findViewById(R.id.title)
private val subtitle: TextView = itemView.findViewById(R.id.subtitle)
fun bind(recyclerViewItem: RecyclerViewItem) {
title.text = recyclerViewItem.title
subtitle.text = recyclerViewItem.subtitle
itemView.setOnClickListener { itemClick(recyclerViewItem) }
}
}
}
package com.mj.recyclerview_sample
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerViewItems: ArrayList<RecyclerViewItem> = ArrayList()
recyclerViewItems.add(RecyclerViewItem(1, "title1", "subtitle1"))
recyclerViewItems.add(RecyclerViewItem(2, "title2", "subtitle2"))
recyclerViewItems.add(RecyclerViewItem(3, "title3", "subtitle3"))
recyclerViewItems.add(RecyclerViewItem(4, "title4", "subtitle4"))
recyclerViewItems.add(RecyclerViewItem(5, "title5", "subtitle5"))
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
val adapter = RecyclerViewAdapter(recyclerViewItems) { recyclerViewItem ->
Toast.makeText(this, "${recyclerViewItem.title} 클릭", Toast.LENGTH_SHORT).show()
}
recyclerView.adapter = adapter
val newRecyclerViewItems: ArrayList<RecyclerViewItem> = ArrayList()
newRecyclerViewItems.add(RecyclerViewItem(1, "title1", "subtitle1"))
newRecyclerViewItems.add(RecyclerViewItem(2, "title2", "subtitle2"))
newRecyclerViewItems.add(RecyclerViewItem(3, "title3", "subtitle3"))
newRecyclerViewItems.add(RecyclerViewItem(4, "title4", "subtitle4"))
newRecyclerViewItems.add(RecyclerViewItem(5, "title5", "subtitle5"))
newRecyclerViewItems.add(RecyclerViewItem(6, "title6", "subtitle6"))
newRecyclerViewItems.add(RecyclerViewItem(7, "title7", "subtitle7"))
adapter.setData(newRecyclerViewItems)
}
}