【问题标题】:How to notify Composition if a public property of Stable type changes?如果 Stable 类型的公共属性发生变化,如何通知 Composition?
【发布时间】:2023-01-03 22:53:14
【问题描述】:

正如 Jetpack compose 文档中所述,稳定类型必须遵守以下约定。

  1. 两个实例的 equals 结果将永远相同 同样的两个实例。
  2. 如果类型的公共属性发生更改,Composition 将收到通知。
  3. 所有公共财产类型也 稳定的。

    第一份和第三份合同很简单。我怎样才能遵守第二点?

    例如,我有一个名为 User 的稳定类型

    data class User(val username: String, var email: String)
    

    并且我在应用程序流程期间更改了电子邮件,我该如何通知组合?

【问题讨论】:

  • 你想出来了吗?

标签: android android-jetpack-compose


【解决方案1】:

根据Jetpack Compose Stability Explained

重要的是要注意参数不必是不可变的,只要将所有更改通知 Compose 运行时,它们就可以是可变的。对于大多数类型来说,这将是一个不切实际的契约,但是 Compose 提供了可变类来为你维护这个契约,例如MutableStateSnapshotStateMap/List/等。因此,将这些类型用于您的可变属性将允许您的类维护 @Stable 的契约。

同一篇文章中的示例建议确保班级中的任何 var 实际上是 MutableState

@Stable
class MyStateHolder {
  var isLoading by mutableStateOf(false)
}

在您的示例中,它可能是这样的:

@Stable
data class User(val username: String) {
  var email by mutableStateOf("")
}

请注意,此时 data class 可能并不理想,因为它生成的某些功能(copyequals)不适用于现在可变的电子邮件字段。

【讨论】:

    【解决方案2】:

    Compose 有一个特殊的State 类型,允许您在需要重新组合时发出通知。这是启动重组的最常见方式。

    data 类是一个很好的工具,可以立即为您提供所有字段的 copy,但您应该避免使用 var 并仅对您的字段使用 val 以避免错误。

    因此,更新字段的基本示例如下所示:

    var state by remember { mutableStateOf(User(username = "", email = "")) }
    TextField(
        value = state.username,
        onValueChange = {
            state = state.copy(username = it)
        }
    )
    

    你可以用同样的方式使用Flow/LiveData,因为它们可以在StatecollectAsState/observeAsState中收集。

    更多信息可以在 Compose documentation 中找到,包括解释基本原理的 this youtube video

    【讨论】:

    • 你还没有回答问题。公共属性更改时如何通知组合,期间
    猜你喜欢
    • 2016-11-18
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    相关资源
    最近更新 更多