[英]Why does my observer doesn't get notified when a new item is added to my livedata list
將項目添加到 LiveData 列表時,我需要獲取一個觀察者事件。
// 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
正在查看對相同的 object。 所以沒有區別,這意味着它不會觸發更新(舊列表確實發生了變化,但它所能做的就是與新列表進行比較,這是同一個列表)。 您可以像這樣在后台更改舊數據的其他錯誤,同時向外推動“新”值
MutableLiveData
包含一個鞋子列表,你需要在你的視圖 model 中單獨聲明它們:
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(...))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.