簡體   English   中英

Android Jetpack compose - 觀察第二次更改后未觸發的實時數據

[英]Android Jetpack compose - Observe a live data not trigger after second channge

我正在使用 viewModel 將數據傳遞給我的撰寫視圖。 問題是我想通過在 viewModel 中的模型中歸檔來處理展開和折疊視圖。 因此,如果某些 UI 單擊 expand 方法,我將調用 viewModel 和 doExpand 方法,如下所示:

 private val _acquiredCoupons = MutableLiveData<List<AcquiredCoupon>>(listOf())
 val acquiredCoupons: LiveData<List<AcquiredCoupon>> = _acquiredCoupons

    fun doExpand(coupon : AcquiredCoupon){
        
        val index = _acquiredCoupons.value?.indexOf(coupon) ?: -1
         val newItems = _acquiredCoupons.value?.toMutableList().also {
            it?.get(index)?.isExpanded = true
        }
        _acquiredCoupons.value = newItems
        Timber.i("Mahdi $index")
    }

但問題是在撰寫 UI 中更新模型后不會觸發並且不會發生重新撰寫! 我正在觀察這樣的實時數據:

val items = viewModel.acquiredCoupons.observeAsState(initial = emptyList())

在您的觀察代碼中,您需要使用observeAsState ,因此您的視圖將使用更改該值的任何 LiveData 更新重新組合。

val items by viewModel.acquiredCoupons.observeAsState()

問題很可能是您將原始值傳遞給Composable (請在有機會時在您的問題中包含示例代碼段)。 如果認為該值等於前一個值,則不會發生重組。

解決此問題的一種方法是將State對象本身傳遞給目標Composable

例如,如果您是這樣設置的:

@Composable
fun CouponBar(
    coupons: List<Coupon>
) { ... }

然后嘗試

@Composable
fun CouponBar(
    coupons: State<List<Coupon>>
) { ... }

如果有人在觀察列表時仍然遇到此問題,我發現一個很好的解決方案是在 ViewModel/LiveData 中從List切換到SnapshotStateList

從這個轉換后:

class MainViewModel : ViewModel() {
    val itemLiveData: LiveData<List<String>>
        get() = items

    private val items = MutableLiveData<List<String>>()
    private val itemImpl = mutableListOf<String>()

    fun addItem(name: String){
        itemImpl.add(name)
        items.postValue(itemImpl)
    }
}

對於這種形式:

class MainViewModel : ViewModel() {
    val itemLiveData: LiveData<SnapshotStateList<String>>
        get() = items

    private val items = MutableLiveData<SnapshotStateList<String>>()
    private val itemImpl = mutableStateListOf<String>()

    fun addItem(name: String){
        itemImpl.add(name)
        items.postValue(itemImpl)
    }
}

當項目添加到列表中時,我的組合按預期工作

@Composable
fun ItemList(model: MainViewModel = viewModel()) {
    Column {
        Button( 
            onClick = { model.addItem("New item") },
            content = { Text(text="Add item") } 
        )
                
        val items by model.itemLiveData.observeAsState()

        if( items.isNullOrEmpty() ) {
            Text(text = "No items")
        }
        else {
            items?.forEach { item ->
                Text(text=item)
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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