如何使 registerForActivityResult 的参数可组合?

cev*_*ing 3 android kotlin android-permissions android-jetpack-compose

以下代码来自Android 开发人员文档。它解释了如何请求权限。

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // features requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    }
Run Code Online (Sandbox Code Playgroud)

我尝试在我的应用程序中使用该代码。当isGranted为真时我尝试渲染我的主用户界面。但它不起作用,因为我收到以下错误:

@Composable 调用只能在 @Composable 函数的上下文中发生

我想知道为什么会发生这种情况,因为我从可组合上下文中调用启动器。是否有必要将调用堆栈中的每个函数都标记为@Composable?如果是这样,如何将闭包传递给可registerForActivityResult组合项?

Nik*_*ski 5

您应该定义一个在结果返回后更新的状态。记住的状态可以在有状态可组合项中或作为参数出现。更新记住的状态将触发重组。

Lambda 传入registerForActivityis 回调,在重组时会多次传递,但只有最后一次传递的回调会被回调。

你可以这样做:

@Composable
fun OnPermissionGranted(permission : String, launch : Boolean, onGranted : @Composable () -> Unit ){
    val context = LocalContext.current
    var granted by remember { mutableStateOf(checkIfGranted(context) ) }
    val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestPermission()){
        if(it){
            granted = true
        }
    }

    if(!granted && launch){
        launcher.launch(permission)
    }
    if(granted){
        onGranted()
    }
}
Run Code Online (Sandbox Code Playgroud)