簡體   English   中英

為什么將新項目添加到我的 livedata 列表時我的觀察者沒有收到通知

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM