0

我有这个过去可以正常工作的可组合,但现在在一些库更新后它就不行了。
我正在使用 aViewModel来保存从 a 中返回的图像ActivityResultContracts.TakePicture()并将其显示Image在 aBox中。
PhotoButton组合项工作正常并返回正确的图像 url,但我的主要可组合项中的图像字符串始终为空。

SamplePage.kt

@Composable
fun SamplePage(navController: NavController) {

    val inputViewModel = InputViewModel()
    val context = LocalContext.current

    Column{
        InputFields(inputViewModel, navController, setPerm)
    }
}

@Composable
fun InputFields(inputViewModel: InputViewModel, navController: NavController) {
    val image: String by inputViewModel.image.observeAsState("")

    Column() {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Box(contentAlignment = Alignment.Center) {
                val painter = rememberImagePainter(data = image)
                Image(
                    painter = painter,
                    contentScale = ContentScale.FillWidth,
                    contentDescription = null
                )
                if (painter.state !is ImagePainter.State.Success) {
                    Icon(
                        painter = painterResource(id = R.drawable.icon),
                        contentDescription = null
                    )
                }
            }
            PhotoButton() {
                inputViewModel.onImageChange(it)
            }
        }
    }
}

class InputViewModel : ViewModel() {
    private val _image: MutableLiveData<String> = MutableLiveData("")
    val image: LiveData<String> = _image

    fun onImageChange(newImage: String) {
        _image.value = newImage
    }
}

PhotoButton.kt

@Composable
fun PhotoButton(onValChange: ((String) -> Unit)?){
    val context = LocalContext.current
    val storageDir: File? = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    val file = File(storageDir, "picFromCamera")
    val uri = FileProvider.getUriForFile(
        context,
        context.packageName.toString() + ".provider",
        file
    )

    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) {
        if (onValChange != null) {
            onValChange(uri.toString())
        }
    }

    FAB() {
        launcher.launch(uri)
    }
}
4

1 回答 1

1

您正在为每个重组创建一个新的视图模型:

val inputViewModel = InputViewModel()

相反,您应该使用viewModel():它将在第一次调用时创建一个新的视图模型,并将其存储以供将来调用:

val inputViewModel = viewModel<InputViewModel>()

在撰写状态文档中查看有关视图模型使用的更多信息。

于 2021-10-04T17:20:30.377 回答