Jetpack Compose MutableLiveData 不更新 UI 组件

Nic*_*age 6 android viewmodel android-livedata android-jetpack android-jetpack-compose

我试图通过包含下载 ID 和进度值的数据对象列表一次显示多个下载进度条。此对象列表的值正在正确更新(通过日志记录显示),但 UI 组件在其初始值从 null 更改为第一个进度值后将不会更新。请帮忙!

我看到有类似的问题,但他们的解决方案对我不起作用,包括附加观察员。

class DownLoadViewModel() : ViewModel() {
   ...
   private var _progressList = MutableLiveData<MutableList<DownloadObject>>()
   val progressList = _progressList // Exposed to the UI.
   ...
   
   //Update download progress values during download, this is called 
   // every time the progress updates.
   val temp = _progressList.value
   temp?.forEach { item ->
      if (item.id.equals(download.id)) item.progress = download.progress
   }
   _progressList.postValue(temp)
   ...
}
Run Code Online (Sandbox Code Playgroud)

用户界面组件

@Composable
fun ExampleComposable(downloadViewModel: DownloadViewModel) {
    val progressList by courseViewModel.progressList.observeAsState()
    val currentProgress = progressList.find { item -> item.id == local.id }
    ...
    LinearProgressIndicator(
        progress = currentProgress.progress
    )
    ...
}
Run Code Online (Sandbox Code Playgroud)

gao*_*way 10

查了很多文字,解决ViewModel中List不更新Composable的问题。我尝试了三种方法都没有效果,比如:LiveData、MutableLiveData、mutableStateListOf、MutableStateFlow

根据测试,发现值发生了变化,但是界面没有更新。文档中说,只有当State的值发生变化时,页面才会更新。根本问题是数据问题。如果没有更新,说明State没有监控到数据更新。

上面的方法对于添加和删除是有效的,但是单独更新不行,因为我更新了T中的元素,但是对象没有改变。

解决方案是深复制。


    fun agreeGreet(greet: Greet) {
        val g = greet.copy(agree = true)  // This way is invalid 
        favourites[0] = g
    }
Run Code Online (Sandbox Code Playgroud)


    fun agreeGreet(greet: Greet) {
        val g = greet.copy() // This way works
        g.agree = true
        favourites[0] = g
    }

Run Code Online (Sandbox Code Playgroud)

很奇怪,浪费了很多时间,希望对需要更新的人有帮助。