카테고리 없음

[Android] DiffUtil / AsyncListDiffer / ListAdapter 사용법

콩드로이드 2024. 9. 29. 20:28

같은 예제로 DiffUtil / AsyncListDiffer / ListAdapter을 사용하자면 아래와 같습니다 

 

DiffUtil

package com.example.co_timer

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.bumptech.glide.Glide
import com.example.co_timer.databinding.LayoutItemBinding

class MainAdapter(val mItems : ArrayList<Item>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun getItemCount() = mItems.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = mItems[position]
        (holder as ItemHolder).bind(item)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {
        return ItemHolder(LayoutItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }

    class ItemHolder(private val binding: LayoutItemBinding) : ViewHolder(binding.root) {
        fun bind(data: Item) = with(binding) {
            tvSub.text = data.sub
            tvTitle.text = data.title

            Glide.with(ivImg)
                .load(data.imgUrl)
                .into(ivImg)
        }
    }

    private fun updateItems(newItems: List<Item>) {
        val diffResult = DiffUtil.calculateDiff(Diff(mItems, newItems))
        mItems.clear()
        mItems.addAll(newItems)
        diffResult.dispatchUpdatesTo(this)
    }

    fun deleteItem() {
        val idx = (0 until mItems.size).random()
        val newList = mItems.toMutableList()
        newList.removeAt(idx)
        updateItems(newList)
    }

    class Diff(private val oldList: List<Item>, private val newList: List<Item>) : DiffUtil.Callback() {

        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldList[oldItemPosition].id == newList[newItemPosition].id
        }

        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            return oldList[oldItemPosition] == newList[newItemPosition]
        }

        override fun getNewListSize() = newList.size
        override fun getOldListSize() = oldList.size
    }
}

 

AsyncListDiffer

package com.example.co_timer

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.bumptech.glide.Glide
import com.example.co_timer.databinding.LayoutItemBinding

class MainAdapter : RecyclerView.Adapter<ViewHolder>() {


    private val asyncListDiffer = AsyncListDiffer(this, Diff)

    override fun getItemCount() = asyncListDiffer.currentList.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = asyncListDiffer.currentList[position]
        (holder as ItemHolder).bind(item)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ItemHolder(LayoutItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }

    class ItemHolder(private val binding: LayoutItemBinding) : ViewHolder(binding.root) {
        fun bind(data: Item) = with(binding) {
            tvSub.text = data.sub
            tvTitle.text = data.title

            Glide.with(ivImg)
                .load(data.imgUrl)
                .into(ivImg)
        }
    }

    fun submitList(items : ArrayList<Item>) {
        asyncListDiffer.submitList(items)
    }

    fun deleteItem() {
        val idx = (0 until asyncListDiffer.currentList.size).random()
        val newList = ArrayList(asyncListDiffer.currentList)
        newList.removeAt(idx)
        asyncListDiffer.submitList(newList)
    }

    object Diff : DiffUtil.ItemCallback<Item>() {
        override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
            return oldItem == newItem
        }
    }
}

 

ListAdapter

package com.example.co_timer

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.bumptech.glide.Glide
import com.example.co_timer.databinding.LayoutItemBinding

class MainAdapter : ListAdapter<Item, MainAdapter.ItemHolder>(Diff) {


    override fun getItemCount() = currentList.size

    override fun onBindViewHolder(holder: ItemHolder, position: Int) {
        val item = currentList[position]
        holder.bind(item)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {
        return ItemHolder(LayoutItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
    }

    class ItemHolder(private val binding: LayoutItemBinding) : ViewHolder(binding.root) {
        fun bind(data: Item) = with(binding) {
            tvSub.text = data.sub
            tvTitle.text = data.title

            Glide.with(ivImg)
                .load(data.imgUrl)
                .into(ivImg)
        }
    }


    fun deleteItem() {
        val idx = (0 until currentList.size).random()
        val newList = ArrayList(currentList)
        newList.removeAt(idx)
        submitList(newList)
    }

    object Diff : DiffUtil.ItemCallback<Item>() {
        override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
            return oldItem == newItem
        }
    }
}