MutableListのMutableLiveDataではなくListのMutableLiveDataにする
MutableLiveData<MutableList<Int>>
のようなLiveData
を使う場合、MutableList
のadd
メソッドなど要素を追加・削除するメソッドを呼び出して
更新しても、データの更新は通知されない。
以下のようなリストのLiveData
を持つViewModel
を用意し、
class FooViewModel : ViewModel() {
val list = MutableLiveData<MutableList<Int>>(mutableListOf())
fun add(num: Int) {
list.value.add(num)
}
fun remove(num: Int) {
list.value.minus(num)
}
}
Fragment
でリストをobserve
する。
class FooFragment : Fragment() {
private val viewModel : FooViewModel by viewModels()
fun onCreateView(...) {
viewModel.list.observe(viewLifecycleOwner) {
// viewModel.list が更新されたときに実行する処理
}
}
}
FooViewModel
のadd
、remove
が呼ばれるとlist
のvalue
が変更されるが、上記observe
には通知されない。
LiveData
はpostValue
かsetValue
が呼ばれたときに変更を通知するが、
破壊的メソッドを呼び出してもvalueに入っている参照が変わらないのでsetValue
が呼び出されないため。
add、minusメソッドが使えないならLiveDataにする
LiveData
としての旨味がないのでMutableList
ではなくただのList
にする。
class FooViewModel : ViewModel() {
val list = MutableLiveData<List<Int>>(emptyListOf())
...
}
Listだとadd、minusが使えないことへの対策
immutableなList
クラスにしたことでadd
、minus
メソッドが使えなくなったので
更新メソッドを非破壊のメソッドを使って以下のように書き換える。
class FooViewModel : ViewModel() {
val list = MutableLiveData<MutableList<Int>>(mutableListOf())
fun add(num: Int) {
list.value = (list.value ?: emptyList()) + num
}
fun remove(num: Int) {
list.value = (list.value ?: emptyList()) - num
}
}
これでlist.value
への代入となり、setValue
が呼ばれることになり、LiveData
としての通知がしっかり行なわれる。
\確かな知識を身に着けたい、Androidアプリ開発を学びたい人にオススメ!/