【问题标题】: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] 的条件。

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案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&lt;...&gt;,你可以在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 不起作用,这就是我发布解释的原因。

      【讨论】:

        猜你喜欢
        • 2022-08-14
        • 1970-01-01
        • 1970-01-01
        • 2022-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        相关资源
        最近更新 更多