kotlin 在Android Jetpack Compose中进行第二次更改后不会触发观察LiveData

3bygqnnd  于 2023-08-07  发布在  Kotlin
关注(0)|答案(4)|浏览(221)

我正在使用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())

bqf10yzr

bqf10yzr1#

如果任何人在观察列表时仍然有这个问题,我发现一个很好的解决方案是在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按预期工作

@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)
            }
        }
    }
}

rlcwz9us

rlcwz9us2#

在您的观察代码中,您需要使用observeAsState,因此您的视图将使用任何更改值的LiveData更新进行重组。
val items by viewModel.acquiredCoupons.observeAsState()

rlcwz9us

rlcwz9us3#

问题很可能是您正在将原始值传递给Composable(请在有机会时包含一个示例片段到您的问题中)。如果认为该值等于前一值,则不会发生重组。
解决这个问题的一种方法是将State对象本身传递给目标Composable
例如,如果你这样设置:

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

字符串
那就试试

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

vlf7wbxs

vlf7wbxs4#

您的liveData中使用的是list,而不是MutableList,因此会出现此问题。

相关问题