LiveData에서 List<T> 변경을 옵저빙하는 방법은?
_____- >에서 리스트 변경을 어떻게 옵저빙하나요?
A1: LiveData
- >를 옵저빙할 때는 LiveData 객체에 옵저버를 등록하고, 값이 변경될 때마다 onChanged() 콜백이 호출됩니다. 예를 들어:
```kotlin
val liveDataList: LiveData
- > = ...
liveDataList.observe(this, Observer { list ->
// list가 변경될 때마다 호출됨
// 변경된 리스트로 UI 업데이트 등 처리
})
```
---
Q2: List
A2: LiveData는 리스트 그 자체(List 객체)의 변경을 감지하지, 리스트 내부 아이템의 개별 변경은 감지하지 못합니다. 즉, 같은 리스트 객체에 내부 아이템이 변경되어도 LiveData는 변경을 인지하지 않습니다. 반드시 리스트 객체를 새로운 인스턴스로 교체해야 옵저버가 호출됩니다.
---
Q3: 내부 아이템이 변경될 때도 업데이트를 받으려면 어떻게 해야 하나요?
A3: 리스트 내부 아이템이 변경되었음을 반영하려면, 변경 후 리스트를 새로 복사해서 MutableLiveData에 다시 setValue() 또는 postValue() 해야 합니다.
예:
val newList = oldList.toMutableList()
newList[index] = modifiedItem
_liveData.value = newList // 변경 알림 발생
```
---
Q4: MutableLiveData의 setValue와 postValue 차이는 무엇인가요?
A4: setValue()는 메인 스레드에서 호출해야 하며 즉시 값이 변경되고 옵저버가 알림을 받습니다. postValue()는 백그라운드 스레드에서 호출 가능하며, 메인 스레드에 일정 시간 후 값 변경 알림을 보냅니다.
---
Q5: LiveData 리스트 변경 감지를 위해 DiffUtil을 사용하는 것이 좋은가요?
A5: 네, UI 성능 향상을 위해 리스트 변경 시 단순히 교체하지 않고, DiffUtil을 사용하여 변경분만 반영하는 것이 좋습니다. DiffUtil로 차이를 계산하여 RecyclerView.Adapter의 notifyItemChanged 등 적절하게 호출하면 효율적입니다.
---
요약:
- LiveData
- >는 리스트 객체 변경을 옵저빙함
- 리스트 내부 애플리케이션 변경은 새 리스트 객체 생성 및 setValue/postValue 호출 필요
- 내부 변경 감지 목적이라면 리스트를 교체해야 LiveData가 알림
- UI 성능 최적화 위해 DiffUtil과 함께 사용하는 것을 권장함
LiveData는 기본적으로 값의 참조(reference) 변경을 감지하기 때문입니다.
즉, 리스트 객체 내의 요소들을 변경해도 리스트 객체 참조가 바뀌지 않으면 옵저버가 동작하지 않습니다.
이해를 돕기 위해 LiveData<List
--- 기본 동작 및 문제점 - LiveData가 hold하는 값은 `List
- 리스트 내부 요소를 추가하거나 삭제해도, 리스트 객체의 참조는 그대로이므로 LiveData 값이 변경된 것으로 인식되지 않습니다.
- 따라서 UI에 변화가 있어도 옵저버가 호출되지 않고, 화면에 변경이 반영되지 않습니다.
예를 들어 다음과 같은 코드가 있다고 가정합시다: ```kotlin val itemsLiveData = MutableLiveData
- >() // 기존 리스트에 요소 추가 val currentList = itemsLiveData.value ?: emptyList() val newList = currentList.toMutableList() newList.add("새로운 항목") itemsLiveData.value = newList ``` - 여기서는 MutableList를 새로 만들어서 LiveData에 새로 할당했기 때문에 `value`의 참조가 달라져 옵저버가 호출됩니다.
- 그러나 만약 `itemsLiveData.value?.add("새로운 항목")` 식으로 직접 원본 리스트를 수정하면 호출되지 않습니다.
1. 리스트 변경 시 새로운 리스트 객체로 할당하기 가장 안전하고 기본적인 방법은 리스트 내부 요소를 변경할 때마다 새로운 리스트 객체를 만들어서 LiveData에 할당하는 것입니다.
```kotlin // 기존 리스트 복사 후 수정 val currentList = itemsLiveData.value ?: emptyList() val updatedList = currentList.toMutableList() updatedList.add(newItem) itemsLiveData.value = updatedList ``` - 이렇게 하면 LiveData의 참조가 변경되어 데이터 변경을 감지합니다.
- UI 옵저버는 새로운 리스트를 받으므로 자동으로 UI를 업데이트할 수 있습니다.
---
2. `MutableLiveData
- >`와 `postValue()`를 함께 사용하기 - LiveData는 값 변경을 메인 스레드에서 해야 하므로, 백그라운드 스레드에서 변경할 때는 `postValue()`를 써야 합니다.
- 이 경우에도 역시 새로운 리스트 객체로 만들어 postValue 호출을 해야 합니다.
```kotlin val currentList = itemsLiveData.value ?: emptyList() val updatedList = currentList.toMutableList() updatedList.add(newItem) itemsLiveData.postValue(updatedList) ``` ---
3. List의 원소 변경 감지 (복잡한 경우) - 단순히 리스트에 항목 추가나 삭제 외에 리스트 내부 아이템 객체의 속성 변경을 감지하는 것은 LiveData에서 직접 지원하지 않습니다.
- 예를 들어 `List
이런 경우 고려할 방법은: - 아이템 객체에 Observable 패턴(예: ObservableField, RxJava의 Observable 등)을 적용해 내부 속성 변화를 감지. - 아이템 변경 시 전체 리스트를 복사해서 LiveData에 다시 할당. - 리스트 대신 `LiveData
작성자:
김준혁 [비회원]
| 작성일자: 1년 전
2025-05-25 12:40:53
조회수: 232 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 232 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.