티스토리 뷰
ViewModel의 기본적인 사용 목적은 UI Controller에서 보여줄 데이터를 관리하는 것이다. 일반적으로 ViewModel에 데이터를 LiveData로 관리하고 UI Controller가 그 데이터를 Observing 하는 구조로 만든다. 여기서 단일 데이터에 LiveData를 사용하면 문제가 되지 않지만 리스트에 LiveData를 단일 데이터처럼 적용하려고 하면 제대로 동작하지 않는다. 즉, 리스트 내부의 아이템 추가, 삭제와 같은 변경 사항이 일어나도 Observer에 등록된 콜백이 호출되지 않는다는 것이다.
위 그림의 View와 ViewModel의 관계에서 어떻게 리스트 데이터를 LiveData로 관리해서 내부 아이템의 변경사항까지 Observing 하도록 만들 수 있을까?
LiveData와 List를 따로 관리하기
class MyViewModel : ViewModel() {
private val list = mutableListOf<Item>()
private val _itemList = MutableLiveData<List<Item>>()
val itemList: LiveData<List<Item>> = _itemList
init {
_itemList.value = list
}
fun addItem(item: Item) {
list.add(item)
_itemList.value = list
}
fun removeItem(item: Item) {
list.remove(item)
_itemList.value = list
}
}
이렇게 하면 리스트의 아이템을 추가/삭제할 때도 LiveData의 value가 변경되기 때문에 Observer의 콜백이 호출된다.
LiveData를 Observing하는 코드는 다음과 같다. 이처럼 Observe에서 리스트를 업데이트 해 줄 수 있을 것이다.
myViewModel.itemList.observe(owner, Observer { itemRecyclerAdapter.updateList(it) })
Custom LiveData 만들기
이렇게 매번 LiveData를 함께 바꿔줘야 하는 작업이 번거롭다면 아래와 같이 Custom LiveData를 만들어 사용할 수도 있다.
class ListLiveData<T> : MutableLiveData<MutableList<T>>() {
private val temp = mutableListOf<T>()
init {
value = temp
}
fun add(item: T) {
temp.add(item)
value = temp
}
fun addAll(items: List<T>) {
temp.addAll(items)
value = temp
}
fun remove(item: T) {
temp.remove(item)
value = temp
}
fun clear() {
temp.clear()
value = temp
}
}
ListLiveData를 사용한다면 ViewModel 코드는 아래처럼 단순화 될 것이다.
class MyViewModel : ViewModel() {
val itemList = ListLiveData<Item>()
fun addItem(item: Item) {
itemList.add(item)
}
fun removeItem(item: Item) {
itemList.remove(item)
}
}
이렇게 커스텀한 itemList를 Observing하는 코드는 다음과 같다.
myViewModel.itemList.observe(owner, Observer { itemRecyclerAdapter.updateList(it) })
마무리
여기까지 RecyclerView의 데이터를 ViewModel에서 LiveData로 관리하는 방법을 알아보았다. 이후 포스팅에서는 이런 상황에서 효율적으로 리스트의 아이템을 변경할 수 있는 ListAdapter에 대해 알아보려고 한다.
[참고한 사이트]
'Mobile > Android' 카테고리의 다른 글
[Android] ListAdapter로 리스트 효율적으로 관리하기 (with DiffUtil) (2) | 2020.06.12 |
---|---|
[Android] Context 제대로 알고 사용하자! (0) | 2020.06.10 |
[Android] Retrofit2 + Gson 사용하기 (with Kotlin) (0) | 2020.05.07 |
[Android] Properties 값 Java/xml 파일에서 읽어오기 (0) | 2020.04.08 |
[Android] Bitmap Compress Format (JPEG vs PNG vs WEBP) (0) | 2020.03.24 |
- Total
- Today
- Yesterday
- AndroidStudio
- RecyclerView
- MSSQL
- SQLD
- pecs
- AsyncListDiffer
- ViewHolder
- python3
- kotlin
- 알고리즘
- Android
- SQLiteOpenHelper
- 파이썬
- Algorithm
- 안드로이드
- covariance
- GitHub
- 내용제공자
- Python
- 위험권한
- SQL Server
- gson
- 부스트코스
- RuntimeException
- SOCKET
- SQL
- 프로그래머스
- DiffUtil
- personal access token
- Java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |