当项目被添加到LiveData列表时,我需要获得一个Observer事件。
// mutable live data list of shoes
private var _shoesList = MutableLiveData<List<Shoe>>()
val shoesList: LiveData<List<Shoe>>
get() = _shoesList
当我将新项目添加到列表时
_shoesList.value?.plus(Shoe(name,sizeDouble,company,description))
_shoesList.value = _shoesList.value // so the observer gets notified
观察员代码:
val viewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
观察器块内的代码从未到达
viewModel.shoesList.observe( viewLifecycleOwner , Observer { newShoe ->
Log.i("ShoeListFragment","i am inside the observer block")
})
我还是一个初学者,所以任何帮助都会受到赞赏:(
plus
返回一个新列表,它是添加了新Shoe
的原始列表-它不会影响原始列表。plusAssign
添加到原始。
这两个都是operator
函数(请参阅operator
关键字(,这意味着您可以像以下那样使用它们:
// plus
shoesList + newShoe
// plusAssign
shoesList += newShoe
如果您不熟悉+=
,则较长的版本为shoesList = shoesList + newShoe
。所以你可以看出你正在用这个值重新分配shoesList
的值。仅仅做shoesList + newShoe
不会改变任何事情——你只需要将它们组合起来,然后对结果什么都不做。
但是您的LiveData
包含一个不可变的List
类型,而不是MutableList
类型,因此您无法添加。这里不能使用plusAssign
,您需要使用plus
创建一个新的列表(原始列表与新元素组合(,然后将其分配给您的LiveData
:
// store the result of your plus call
val newShoes = _shoesList.value?.plus(Shoe(name,sizeDouble,company,description))
_shoesList.value = newShoes // you need to assign the new list anyway!
所以与你已经拥有的相比没有太大的变化,但希望这能让你更好地了解正在发生的事情!如果使用MutableList
,您可以只执行plusAssign,但是的,您必须重新分配value
,以推动它更新其观察者。
老实说,创建一个新列表通常更安全,因为你没有修改原始列表,其他东西可能已经存储了对该列表的引用。例如,如果你在RecyclerView
中使用DiffUtil
,它会将旧列表与新列表进行比较。。。如果更改旧对象,然后将其作为新对象,则DiffUtil
将查看对同一对象的两个引用。因此没有区别,这意味着它不会触发更新(旧列表确实发生了更改,但它所能做的就是与新列表进行比较,后者是同一列表(。你可以让其他bug像那样在后台更改旧数据,同时向外推一个"错误";新的";值
MutableLiveData
包含一个鞋的列表,您需要在视图模型中单独声明它们:
private var _shoes = mutableListOf<Shoe>()
private var _shoesList = MutableLiveData<List<Shoe>>(_shoes)
并将LiveData
暴露给任何想要监听数据更改的人:
val shoesList: LiveData<List<Shoe>>
get() = _shoesList
只要您想添加一个新的Shoe
,只需将其添加到_shoes
列表中即可
_show.add(new Shoe(..))
然后更新mutableLiveData以通知监听器:
//notify observers
_shoesList.postValue(_shoes)
_shoes
是一个私有变量,添加此方法可以添加一个新的shoe
:
fun add(shoe: Shoe) = viewModelScope.launch {
_shoes.add(shoe)
//notify observer
_shoesList.postValue(_shoes)
}
这是完整的代码:
class ShoeViewModel() : ViewModel() {
private var _shoes = mutableListOf<Shoe>()
private var _shoesList = MutableLiveData<List<Shoe>>(_shoes)
val shoesList: LiveData<List<Shoe>>
get() = _shoesList
fun add(shoe: Shoe) = viewModelScope.launch {
_shoes.add(shoe)
//notify observer
_shoesList.postValue(_shoes)
}
}
调用这行代码,每次你想添加新鞋
viewModel.add(new Shoe(...))