(Android/안드로이드) ListAdapter 사용 시 반드시 알아야 할 주의사항 정리

개요


1. 구조


2. ❗ 가장 많이 터지는 실수: MutableList 재사용

❌ 잘못된 코드

val list = currentList
list.add(newItem)
adapter.submitList(list)

✅ 올바른 패턴

val newList = currentList.toMutableList().apply {
    add(newItem)
}
adapter.submitList(newList)

3. areItemsTheSame vs areContentsTheSame 차이

object DiffCallback : 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
    }
}
메서드 역할
areItemsTheSame 같은 아이템인가? (식별자 비교)
areContentsTheSame 내용이 같은가? (UI 갱신 필요 여부)

4. data class equals() 의존 문제

// 문제 상황
data class Item(
    val id: Long,
    val name: String,
    var isSelected: Boolean
)

5. submitList() 연속 호출 시 동작 주의

adapter.submitList(list1)
adapter.submitList(list2)

6. currentList 직접 수정 금지

adapter.currentList[0].name = "new"

7. payload 활용 (부분 갱신 최적화)

DiffUtil에서 payload를 반환하면 불필요한 전체 bind를 줄일 수 있습니다.

override fun getChangePayload(oldItem: Item, newItem: Item): Any? {
    return if (oldItem.isSelected != newItem.isSelected) {
        "SELECT_CHANGED"
    } else null
}

override fun onBindViewHolder(
    holder: ViewHolder,
    position: Int,
    payloads: MutableList<Any>
) {
    if (payloads.isNotEmpty()) {
        holder.updateSelection(payloads[0])
    } else {
        super.onBindViewHolder(holder, position, payloads)
    }
}

8. 대용량 리스트 성능 이슈



Related Posts