(Android/안드로이드) ListAdapter submitList 갱신 안되는 문제 해결 방법

✨ 개요


1. 요약


2. 왜 ListAdapter는 값이 변경되어도 갱신되지 않을까?

2-1 Item 모델

data class Item(
    val id: String,
    val text: String,
    var isExpanded: Boolean = false // 현재 펼침 여부
)

2-2 문제 상황 예시

item.isExpanded = true   // 내부 값 변경
submitList(currentList)  // ★ UI 갱신 안 됨

3. ListAdapter & DiffUtil이 목록을 비교하는 방식

ListAdapter에 DiffUtil이 내부적으로 다음과 같은 비교를 수행한다.

object : 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
    }

}
oldItem === newItem   true
oldItem == newItem   true

4. 그래서 immutable(불변) 리스트 + data class copy를 써야 한다

4-1. 잘못된 방식

currentList[position].isExpanded = true
submitList(currentList)  // 갱신 안 됨

4-2. 올바른 방식 (copy로 새로운 객체 생성)

val newList = currentList.toMutableList() // 새로운 리스트 필요
val oldItem = currentList[position]

newList[position] = oldItem.copy(
    isExpanded = !oldItem.isExpanded
)

submitList(newList)

5. 왜 copy()가 중요한가? (참조 변경)


6. ListAdapter에서 불변 객체를 강제하는 이유


7. 정리

문제 원인 해결책
값 변경해도 갱신 안 됨 DiffUtil이 변경을 감지하지 못함 copy()로 새로운 객체 생성
mutable 객체 수정 참조(address)가 동일함 immutable + 새 리스트
submitList 후에도 무반응 내부적으로 동일한 객체로 간주 새로운 객체 + 새로운 리스트 전달

8. 8. Best Practice (실무 팁)



Related Posts