본문 바로가기

TIL

TIL 48일차 - 최종프로젝트

DiffUtil

DiffUtil은 oldItem, newItem의 두 데이터셋을 비교하여 값이 변경된 부분만을 RecyclerView에게 알려줄 수 있다

    companion object {
        val diffCallback = object : DiffUtil.ItemCallback<Place>() {
            override fun areItemsTheSame(oldItem: Place, newItem: Place): Boolean {
                return oldItem.address == newItem.address
            }

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

 

DiffUtil의 경우, 리스트의 아이템이 많으면 하나하나 모두 비교 연산을 수행하므로 작업 시간이 길어질 수 있다. 그래서 안드로이드 공식문서에서는 DiffUtil의 비교 연산의 경우 백그라운드 스레드에서 처리하기를 권고하고 있다. AsyncListDiffer를 사용하면 RecyclerView에서 DiffUtil을 백그라운드에서 실행할 수 있다.

ListAdapter

하지만 ListAdapter를 사용하게 되면 따로 AsyncListDiffer 객체를 생성할 필요 없이 백그라운드 스레드에서 DiffUtil의 비교 연산을 편하게 수행할 수 있게 한다.

class PlaceListAdapter(
    private val onItemClicked: (Place) -> Unit,
    private val listData: List<Place>
) : ListAdapter<Place, PlaceListAdapter.PlaceViewHolder>(diffCallback) {

    class PlaceViewHolder(
        private val binding: RecyclerviewItemBinding,
        private val onItemClicked: (Place) -> Unit
    ) : RecyclerView.ViewHolder(binding.root) {
        fun bind(place: Place) = with(binding) {

            // 데이터 바인딩 설정
            // tvItemAddress.text = place.address

            binding.root.setOnClickListener {
                onItemClicked(place)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlaceViewHolder {
        val view = RecyclerviewItemBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return PlaceViewHolder(view, onItemClicked)
    }

    override fun onBindViewHolder(holder: PlaceViewHolder, position: Int) {
        val currentItem = listData[position]
        holder.bind(currentItem)
    }

    companion object {
        val diffCallback = object : DiffUtil.ItemCallback<Place>() {
            override fun areItemsTheSame(oldItem: Place, newItem: Place): Boolean {
                return oldItem.address == newItem.address
            }

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

 

RecyclerView.Adapter와 다른 ListAdapter의 특징

  •  AsyncListDiffer 객체 없이도 백그라운드 스레드에서 DiffUtil 작업을 수행한다
  • 내부적으로 아이템의 count 역시 처리하므로 getItemCount 메소드도 필수 구현이 아니다
  • ListAdapter 자체에서 submitList를 지원하므로 따로 submitList 메소드를 노출 시킬 필요 없이 바로 Adapter에서 submitList 함수를 사용할 수 있다

'TIL' 카테고리의 다른 글

TIL 50일차 - 최종프로젝트  (0) 2024.05.31
TIL 49일차 - 최종프로젝트  (0) 2024.05.30
TIL 47일차 - 최종프로젝트  (0) 2024.05.28
TIL 46일차 - 최종프로젝트  (0) 2024.05.27
TIL 45일차  (0) 2024.05.08