为啥我的可组合不会在更改 HashMap 的 MutableState 值时重新组合?
Posted
技术标签:
【中文标题】为啥我的可组合不会在更改 HashMap 的 MutableState 值时重新组合?【英文标题】:Why my composable not recomposing on changing value for MutableState of HashMap?为什么我的可组合不会在更改 HashMap 的 MutableState 值时重新组合? 【发布时间】:2021-12-23 11:43:50 【问题描述】:为什么我的可组合不会在更改 HashMap 的 MutableState 值时重新组合。
视图模型
val imageList: MutableState<HashMap<Int, Uri>> = mutableStateOf(HashMap())
fun setImage(imageUri: Uri)
imageList.value[imagePosition] = imageUri
片段
if (viewModel.imageList.value[stepNo] != null && !TextUtils.isEmpty(
viewModel.imageList.value[stepNo].toString()
)
)
Image(
contentDescription = "Recipe",
painter = painterResource(R.drawable.ic_baseline_fastfood_24),
modifier = Modifier
.padding(8.dp)
)
fun permissionCallbacks()
imagePickerListener =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) result ->
if (result.resultCode == Activity.RESULT_OK)
// There are no request codes
val data: Intent? = result.data
val selectedImageUri = data?.data
selectedImageUri?.let viewModel.setImage(it)
requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) isGranted: Boolean ->
if (isGranted)
val galleryIntent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
galleryIntent.type = "image/*"
imagePickerListener?.launch(galleryIntent)
else
我通过调试在 setImage()
方法中正确设置了该值,但如果在更改 hashmap 的值时没有再次调用 viewModel.imageList.value[stepNo]
的条件。
【问题讨论】:
【参考方案1】:mutableStateOf
只能跟踪您何时将一个值替换为另一个值。如果您更改当前值的状态,它无法处理它
您可以使用mutableStateMapOf
代替mutableStateOf(HashMap())
:
val imageList = mutableStateMapOf<Int, Uri>()
---
fun setImage(imageUri: Uri)
imageList[imagePosition] = imageUri
【讨论】:
【参考方案2】:好的,首先,您使用的初始化逻辑包含样板。我的意思是如果你写的是val a = 0
,那很好。您无需在此处指定类型。 val a : Int = 0
是错误的。在你的初始化中你不需要包含MutableState<...>
,你可以在mutableStateOf(...)
的HashMap()
调用中指定hashmap的类型。
好的,其次,您不能将任何类型的数据视为状态(我的意思是 compose 不能)。您可以尝试使用原始类型作为您的存储,或者检查是否存在满足您需要的确切类型,在 Compose 中预构建。
例如,
val a by mutableStateOf("Hello")
会触发重组,而
val a by mutableStateOf(Path())
不会,即使您重新分配整个变量。这是因为Path()
在 Compose 中并不意味着是状态持有者。
如果您实际上用两个 Int 和 Uri 列表替换 Int 和 Uri 的映射,它将按预期工作,因为即使是不可变的 listOf()
也受支持。
现在,您还可以搜索特定的预定义持有者是否支持您的用例。在这种情况下,就像库中添加了 mutableStateListOf()
一样,允许您直接将列表用作常规列表对象,同时仍然是状态持有者。
Philip 说有 mutableStateMapOf(),我没听说过,但既然有 mutableStateListOf()
,它可能也有。
所以是的,对于您的用例,如果存在,它将正常工作,但您应该知道为什么 HashMap 不起作用,这就是我发布解释的原因。
【讨论】:
以上是关于为啥我的可组合不会在更改 HashMap 的 MutableState 值时重新组合?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 AppBar MUI 样式组件在状态更改时不会更改样式?
为啥我的 ko 计算 observable 在其值更改时不会更新绑定的 UI 元素?