开发者问题收集

在 Jetpack Compose 中使用可变对象

2021-09-23
2986

我读到可变对象是不可观察的,因此即使可变对象内的字段被重新分配,也不会发生重组。因此,我不知道如何实现特定任务,非常感谢您的帮助。

基本上,我希望用户能够创建自己的自定义沙拉。他以按钮的形式显示不同的配料,单击后,它们将添加到沙拉对象中。有几个不同的配料类别(和价格),此外,沙拉还有更多属性,例如尺寸、调料、外卖和一些功能。所以总而言之,沙拉应该是一个普通的对象,而不是某种列表。

我的问题是,我想在用户选择食材时重新组合一些 UI(更改订单的图片、标记食材、如果与新食材有冲突则取消标记其他食材等),但不会进行重新组合,因为更改发生在可变对象内部,所以我无法观察到这些变化。

简而言之,当对沙拉对象的属性进行更改时,我该如何更新基于 Jetpack Compose 的 UI?

1个回答

为了在 Compose UI 中反映属性更改,属性必须是可变状态。 可以使用数据类和具有 MutableState 变量的类的组合来捕获 UI 状态。

下面是如何完成此操作的示例。

class Salad(size: Int, dressing: String, priIng: Ingredient) {
        // for primitive properties use MutableState, using delegate here ("by" syntax) can be handy
        var size by mutableStateOf(size)
        var dressing by mutableStateOf(dressing)
        
        var primaryIngredient by mutableStateOf(priIng)

        // for mutable lists use a SnapshotStateList
        val ingredients = mutableStateListOf<Ingredient>()
    
        // or use SnapshotStateMap for mutable map structures in compose UI
        val ingredientsWithQuantity = mutableStateMapOf<Ingredient, Int>()
    }
    
    // immutable data
    data class Ingredient(
        val name: String,
        val calories: Int
    )

更新 salad 对象的属性现在将触发 UI 更新,因为它们由相应的可变状态支持。

var salad = remember { Salad(2, "Dressing", Ingredient("apple", 1)) }

    // update any property as you do with normal objects from any event like user click action
    salad.size += 1
    salad.primaryIngredient = salad.primaryIngredient.copy(name="orange")

要修改不可变数据类的主构造函数成员,可以使用复制函数。

var ing by remember { mutableStateOf(Ingredient("apple", 20)) }

    // to update one or more properties use copy function for data class
    ing = ing.copy(calories = 100)
Om Kumar
2021-10-01