안드로이드 RecyclerView DiffUtil 사용하기

Ddudduu·2021년 11월 12일
0

DiffUtil 란?

  • RecyclerView 에 보여줄 두 가지 리스트 간의 차이를 비교해서 달라진 부분만 업데이트 하도록 도와주는 유틸리티 클래스이다!
  • 이게 왜 필요할까 싶지만, RecyclerView 에서 데이터를 변경하고 나서 보통은 notifyDatasetChanged() 를 호출해 RecyclerView 를 다시 그린다.
    ▶️ cost 가 굉장히 높은 작업이다!
    (보여줄 목록이 수백개라면..? 어느 세월에 다 그럴거니..?)
    ▶️ 바뀐 부분만 딱딱 캐치해서 업데이트하는 DiffUtil 이 등장하게 된 것!


AsyncListDiffer

  • 두 리스트간의 차이를 비교할 때, 백그라운드 스레드에서 비교하도록 도와주는 헬퍼 클래스이다.
  • 이걸 바로 쓰기보다는 ListAdapter 라는 wrapper 클래스를 활용해 더 간편하게 쓸 수 있다!


ListAdapter

  • AsncListDiffer 클래스를 간편하게 쓸 수 있도록 도와주는 클래스이다!
    ▶️ 당연히 리스트간의 차이를 계산할 때는 백그라운드 스레드에서 돌아감!
  • AsyncListDiffer 로 구현할 때보다 코드가 훨-씬 짧아진다고 한다.


기존 RecyclerView 구현 방법 중에 Adapter 만 다르다.

Adapter 구현

class CharacterListAdapter : ListAdapter<Profile, CharacterListAdapter.ViewHolder>(CharacterListDiffCallback) {
  inner class ViewHolder(private val binding: CharacterItemViewBinding) : RecyclerView.ViewHolder(binding.root) {
    fun bind(profile: Profile) {
      binding.apply {
        image.setImageResource(profile.image)
        name.text = profile.name
        favorite.text = profile.favorite
      }
    }
  }

  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val binding = CharacterItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    return ViewHolder(binding)
  }

  override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.bind(getItem(position))
  }

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

    override fun areContentsTheSame(oldItem: Profile, newItem: Profile): Boolean {
      return oldItem.uuid == newItem.uuid
    }
  }
}

위쪽의 ViewHolder 나 onCreateViewHolder, onBindViewHolder 는 RecyclerView.Adapter 구현할 때와 똑같다.

⭐️핵심은⭐️

  • class 를 선언할 때 ListAdpater 를 상속받는다.
  • 내부에 DiffCallback 을 선언하고
  • ListAdpater 에 DiffCallback 를 전달한다.
    요 세가지 이다!

CharacterListDiffCallback 를 살펴보면,

areItemsTheSame() : 아이템이 서로 같은 데이터를 갖고있는지 확인한다.

areContentsTheSame() : 아이템의 내용이 같은지 확인한다.
클래스로 전달한다면 클래스 속성끼리 비교하는 것!

Profile 클래스에 고유 아이디 (UUID) 속성을 추가해 서로 구분되도록 해주었다.

RecyclerView 에 adapter 를 설정하는 방식은 똑같다.
LayoutManager 를 꼭꼭 잊지말고 설정해주자.. 오늘의 삽질 🥲

profile
Android

0개의 댓글