Android Jetpack compose - 观察第二次更改后未触发的实时数据

Ken*_*nji 5 android kotlin android-jetpack android-jetpack-compose

我正在使用 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")
    }
Run Code Online (Sandbox Code Playgroud)

但问题是在撰写 UI 中更新模型后不会触发并且不会发生重新撰写!我正在观察这样的实时数据:

val items = viewModel.acquiredCoupons.observeAsState(initial = emptyList())
Run Code Online (Sandbox Code Playgroud)

Tyl*_*r V 9

如果有人在观察列表时仍然遇到此问题,我发现一个很好的解决方案是从ViewModel/LiveData 中切换ListSnapshotStateList 。

从此转换后:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

对于这种形式:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

当项目添加到列表中时,我的可组合项按预期工作

@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)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Vit*_*mos 0

在您的观察代码中,您需要使用observeAsState,因此您的视图将通过任何更改值的 LiveData 更新来重新组合。

val items by viewModel.acquiredCoupons.observeAsState()

  • 是的,我正在使用这个,但是更新后数据更改中的任何值都不会触发! (2认同)