ListAdatper+DiffUtil vs notifyDataSetChanged()

차누·2025년 1월 14일

notifyDataSetChanged

RecyclerView.Adapter 에 list 를 업데이트하고, notifyDataSetChanged() 를 호출하면 변경된 list 를 기반으로 UI 업데이트를 간편하게 할 수 있었습니다.

단점

방금 보았던 notifyDataSetChanged() 는 structural changes 에 해당하며, 보이는 모든 View 에 대해서 재배치와 재구성을 진행하게 됩니다.

기존 샘플코드와 같이 하나의 아이템의 + 버튼을 클릭할 때마다 notifyDataSetChanged() 로 UI 를 업데이트하는 것은 "0" 이라는 텍스트를 "1" 로 변경하고 싶을 뿐인데, 전체 item 을 재배치하고 재구성하게 되는 것이기에 비효율적입니다.

이러한 점 때문에 공식문서에서는 notifyDataSetChanged() 는 최후의 수단으로 활용하고, 일반적으로는 구체적인 이벤트를 사용하여 item changes 가 실행되도록 구현하는 것이 더욱 효율적이라고 안내하고 있습니다.

DiffUtil

DiffUtil.Callback 클래스를 구현하여 이전 데이터셋과 새로운 데이터셋 간의 차이를 계산하는 메서드를 제공합니다

object HomeDiffCallBack : DiffUtil.ItemCallback<HomeSealedItem>() {

    override fun areItemsTheSame(oldItem: HomeSealedItem, newItem: HomeSealedItem): Boolean {
        return oldItem.javaClass == newItem.javaClass
    }

    override fun areContentsTheSame(oldItem: HomeSealedItem, newItem: HomeSealedItem): Boolean {
        return oldItem == newItem
    }
}
  1. areItemsTheSame: 두 객체가 동일한 항목인지를 결정합니다. 즉 두 객체가 동일한 ID를 가지고 있는지를 확인하여 동일한 항목으로 간주될지를 결정할 수 있습니다. 키값을 비교한다고 보시면 될것 같아요
  2. areContentsTheSame: 두 객체의 내용이 동일한지를 결정합니다. 즉, 두 객체의 데이터가 일치하는지를 확인하는 역할을 합니다. 객체 안에 들어있는 내용을 파악한다고 보시면 될 것 같습니다!

좀더 자세한 예시를 들어 보겠습니다!

기존데이터
[학번 : 1, 학점 : a] 인 학생이 있고
[학번 : 2, 학점 : b] 인 학생이 있습니다.

새로운 데이터
[학번 : 2, 학점 : c] 인 학생이 있고
[학번 : 3, 학점 : b] 인 학생이 있습니다.

우선 areItemsTheSame으로 학번이 같은지 비교합니다! 여기서 1,2 와 2,3을 비교하는데요. 새로운 데이터 2,3이 기준 점입니다!
일단 새로운 데이터에 1은 없습니다. 그럼 1은 비교할 키 2,3이 없으니 아에 삭제 되었다고 간주합니다(비교 자체가 불가능 하기에 연산을 안하는 거죠). 2는 이미 있는 거죠 true를 반환합니다. 3은 없기에 false를 반환합니다.

그럼 areContentsTheSame 입니다. 여기선 키(학번) 안의 학점을 비교하는데요 우선 1은 이미 연산이 불가하므로 논외,
2,3은 각각 true 와 false가 위의 연산에서 반환된 상태입니다. areContentsTheSame 요놈은 위 연산에서 true인 것만 비교합니다!

위 연산에서 true는 학번 2 하나입니다. 학번2의 기존 데이터는 b 바뀐 데이터는 c입니다.
두 데이터가 다르므로 false를 반환합니다. 즉 결과는 [false,(연산 하지 않음)] 인거죠. 또 이 경우만 리스트에 수정 하는거죠.

즉 이렇게 되면 areItemsTheSame인경우 true만 안에 있는 데이터를 비교하면 되기 때문에 notifyDataChanged보다는 연산이 훨씬 줄어듭니다!!

List Adapter

ListAdapter는 데이터셋이 변경될 때 DiffUtil을 사용하여 변경 사항을 감지하고 자동으로 RecyclerView를 업데이트합니다. 이를 통해 코드를 간단하게 유지하면서도 효율적인 RecyclerView 업데이트를 구현할 수 있습니다.

profile
android를 공부하고 정리합니다

0개의 댓글