-
[ANDROID] DiffUtil.ItemCallback + ListAdapterANDROID 2021. 12. 2. 23:57
사용이유
Recycler View는 데이터에 변화가 있을 때 notifyDataSetChanged를 사용하여 데이터의 변화를 뷰에 적용한다.
이 때 Adapter는 전체 데이터 셋중 변경된 아이콘을 찾지못하고 viewHolder를 전부 다시 매칭시켜야 했다.
이로 인해 등장한 것이 RecyclerView의 payload이다. payload는 onBIndViewHolder()가 호출될 때 넘겨받는 객체이다. 특정 position의 holder를 업데이트할 때 payload 값으로 구분하여 뷰를 업데이트 한다.
물론 payload를 사용하여 notifyItemChanged를 통해 특정 데이터의 변화만 인지시키거나 notifyItemRangeChanged를 통해서 특정 데이터의 범위를 인지시킬 수도 있다. 하지만 position을 가지고 수동적으로 데이터를 처리하기에는 불편함이 있을 수 있다.
이럴 때 사용 가능한 것이 DiffUtil이다.
notifyDataSetChanged 위치는 변하지 않고, 아이템간 삽입, 삭제, 이동이 일어낫을 때, 데이터 전체를 매칭시킨다. notifyItemChanged(position: Int, payload: Object) position에 존재하는 아이템이 변경되었을 때 특정 아이템만 매칭시칸다. notifyItemInserted(position: Int) position에 아이템을 추가할 때 매칭시킨다. notifyItemMoved(fromPosition: Int, toPosition: Int) fromPosition에 위치한 아이템이 toPosition으로 옮겨졌을 때 매칭시킨다. notifyItemRangeChanged(positionStart: Int, ItemCount: Int, payload: Object) positionStart 부터 itemCount 만큼의 아이템을 다시 매칭시킨다. https://camposha.info/android-examples/android-diffutil/#gsc.tab=0
Android DiffUtil vs NotifyDataSetChanged usage - Android Examples
Android DiffUtil vs NotifyDatasetChanged differences and tutorial.
camposha.info
DiffUtil.Callback + RecyclerViewAdapter
먼저 RecyclerViewAdpater와 DifferUtil을 사용하게 되면 Item별로 DiffUtil.Callback을 상속받는 클래스를 생성해주어야 한다.
class ItemDiffCallback( private val oldList: List<Item>, private val newList: List<Item> ) : DiffUtil.Callback() { override fun getOldListSize() = oldList.size override fun getNewListSize() = newList.size override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) = oldList[oldItemPosition].id == newList[newItemPosition].id override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = oldList[oldItemPosition] == newList[newItemPosition] }그리고 adapter에 변경된 아이템을 전해줄 때 DiffCallback을 통해 새로운 아이템과 기존 아이템을 비교하여 변화된 데이터만 어댑터가 매칭할 수 있게 해준다.
calculateDiff는 변경된 아이템을 찾아내는데 사용하고, dispatchUpdatesTo는 Adapter로 변경사항을 전달하는데 사용된다.
abstract class ItemListAdapter : RecyclerView.Adapter<ItemListViewHolder>() { private val data = mutableListOf<Item>() ... fun changeItem(newItem: List<Item>) { val diffCallback = ItemDiffCallback(people, newPeople) val diffResult = DiffUtil.calculateDiff(diffCallback) people.clear() people.addAll(newItem) diffResult.dispatchUpdatesTo(this) } }
https://s2choco.tistory.com/33
[Android] ListAdapter로 리스트 효율적으로 관리하기 (with DiffUtil)
이전 포스팅에서 RecyclerView의 아이템을 LiveData로 관리하는 방법에 대해 알아보았다. 이 때 함께 사용하면 좋은 ListAdapter에 대해 소개하려고 한다. RecyclerView를 사용하다보면 아이템을 변경할 일
s2choco.tistory.com
'ANDROID' 카테고리의 다른 글
[ANDROID] kakao login 리젝, 소셜 로그인 리젝, playstore (1) 2022.08.26 [ANDROID] AppbarLayout + tablayout + viewPager2 Scroll issue (Bug) 스크롤 이슈 (버그) (0) 2022.07.09 [Android] SingleLiveEvent(SingleLiveData) 정리 (0) 2022.04.28 [ANDROID] gson progaurd-rules (0) 2022.01.17 [ANDROID] LEAKCANARY dictionary (0) 2021.12.27