【问题标题】:Livedata don't update compose state when list item property has changed列表项属性更改时,Livedata 不会更新撰写状态
【发布时间】:2020-09-20 20:51:46
【问题描述】:

我的问题是使用正确的数据触发了实时数据观察者Observer<T> { state.value = it },但撰写并没有启动重组。只有当我添加一个项目时,所有更改才会传播。如果列表发生了变化,必须对列表本身进行一些检查。我猜它不比较列表项。

@Composable
fun <R, T : R> LiveData<T>.observeAsState(initial: R): State<R> {
    val lifecycleOwner = LifecycleOwnerAmbient.current
    val state = remember { mutableStateOf(initial) }
    onCommit(this, lifecycleOwner) {
        val observer = Observer<T> { state.value = it }
        observe(lifecycleOwner, observer)
        onDispose { removeObserver(observer) }
    }
    return state
}

val items: List<TrackedActivityWithMetric> by vm.activities.observeAsState(mutableListOf())
 LazyColumnForIndexed(
        items = items,
        Modifier.padding(8.dp)
    ) { index, item ->
    ....
    MetricBlock(item.past[1], item.activity.id )

}

【问题讨论】:

  • MutableList 可能是您的问题。一般来说,可变类型对 Compose 来说并不是一件好事。你是怎么修改items的?
  • 它通过 Room 和 Viewmodel 并且都正确更新并且观察者看到了。
  • 好吧,因为我看不到那个代码,所以我不能真正评论它。在摘要中,我建议避免使用MutableListvar
  • 如果我在从数据库中获取项目后输入.shuffled(),所有更改都会反映(当然顺序不同)。

标签: android kotlin android-jetpack-compose


【解决方案1】:

所以在幕后必须有某种哈希比较机制来防止两次渲染相同的项目(需要更详细的答案)。不正确的渲染是由不在TrackedActivityWithMetric 数据类构造函数中的属性引起的。

【讨论】:

  • 您找到解决方案了吗?
  • 同样的问题 - 如果更新的属性不在构造函数中,则列表项不会呈现。
【解决方案2】:

Jetpack Compose 不适用于 MutableList,您需要使用 List 并执行以下操作:

var myList: List<MyItem> by mutableStateOf(listOf())
    private set

用于添加项目:

fun addItem(item: MyItem) {
    myList = myList + listOf(myItem)
}

用于编辑项目:

fun editItem(item: MyItem) {
    val index = myList.indexOf(myItem)
    myList = myList.toMutableList().also {
        it[index] = myItem
    }
}

【讨论】:

  • 这可以观察到吗? IE。 UI 会在 addItem() 上重构吗?
  • 是的,可以观察到
猜你喜欢
  • 2019-11-09
  • 2022-11-30
  • 2020-09-02
  • 2023-04-09
  • 2020-02-10
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多