我想进行一些网络请求,并在 Jetpack Compose 中显示列表结果。我将请求参数传递给列表小部件。但是,即使地图更改,即使添加了 ,列表小部件也无法重新组合key
。
下面是一个小演示:点击按钮后,int 值应该发生变化。
请帮我修复这个问题。
@Preview
@Composable
fun test() {
var map by remember { mutableStateOf(mapOf<String, Any>()) }
Column {
Button(
onClick = {
map = HashMap(map)
}
) {
Text(
text = "Tap"
)
}
key(map) { testWidget1(map = map) }
}
}
@Composable
fun testWidget1(map: Map<String, Any>) {
var testInt by remember { mutableStateOf(0) }
LaunchedEffect(map) {
testInt += 1
request()
}
Text(
text = "$testInt"
)
}
fun request() {
}
有两个问题:
testWidget1
由于映射没有变化,因此不会被重组。尽管您使用 创建新对象HashMap(map)
,但 Compose 会比较对象是否相等,而不是引用身份。这意味着映射的实际内容需要更改,Compose 才能将其检测为不同的内容。您的示例中并非如此。通过使用,
key
您可以明确指示 Compose 在发生更改时丢弃旧的 状态testWidget1
并创建新的状态map
。因此,即使发生map
变化,您仍然需要每次都重置,从 0 开始(并在 LaunchedEffect 中将其设置为 1)。在常规可组合项中testInt
通常不需要这样做。只需将其移除并直接调用即可。key
testWidget1(map = map)
目标:
目标是在点击按钮时更新整数值并确保 UI(具体
testWidget1
)做出相应响应。已发现问题:
每次点击按钮时,地图都会被替换为新
HashMap
实例,而不是更新现有实例。因此,地图testWidget1
不会被重新组合,因为重新组合依赖于观察地图对象本身的变化。已实施的解决方案:
为了解决这个问题,我修改了逻辑,改为更新现有映射,而不是重新分配它。我添加了一个计数器,该计数器会随着每次按钮点击而递增。此计数器用于生成新的键值对并将其插入到现有映射中。
通过就地更新地图(同时保留现有条目),
testWidget1
现在可以检测更改并使用新值重新组合。每次点击都会添加新条目,如、、
key1
等等,这确保地图得到一致修改并触发预期的 UI 更新。key2
key3