Jetpack Compose - 如何在屏幕组合时触发事件

Ne0*_*Ne0 9 android kotlin android-jetpack-compose

我的应用程序使用 OpenID 来验证用户身份。

第一页更像是一个启动屏幕,将用户带到网页以在需要时进行授权,或者仅执行令牌的后台刷新以导航到主屏幕。

我不确定如何在不单击按钮的情况下启动身份验证流程

@Composable
fun LoginScreen(viewModel: LoginViewModel) {
    val ctx = LocalContext.current
    AppTheme {
        Screen()
    }
    viewModel.performLogin(ctx)
}       

Run Code Online (Sandbox Code Playgroud)

执行上述操作是可行的,但当应用程序导航到主屏幕时,它会再次被调用。

fun loginComplete(navController: NavHostController) {
    navController.navigate("main")
}

@Composable
fun MyApp(viewModel: LoginViewModel) {
    val navController = rememberNavController()
    viewModel.setOnLoginCompete(navController, ::loginComplete)
    NavHost(navController, startDestination = "login") {
        composable(route = "login") {
            LoginScreen(viewModel)
        }
        composable(route = "main") {
            MainScreen()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为我不应该像在可组合函数中那样调用 PerformLogin 函数,但我看不到其他方法。我缺少什么?

Ste*_*rix 22

您可以将流程与生命周期回调联系起来。您可以创建实用程序可组合项来处理生命周期事件。

@Composable
fun OnLifecycleEvent(onEvent: (owner: LifecycleOwner, event:Lifecycle.Event) -> Unit) {
    val eventHandler = rememberUpdatedState(onEvent)
    val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)

    DisposableEffect(lifecycleOwner.value) {
        val lifecycle = lifecycleOwner.value.lifecycle
        val observer = LifecycleEventObserver { owner, event ->
            eventHandler.value(owner, event)
        }

        lifecycle.addObserver(observer)
        onDispose {
            lifecycle.removeObserver(observer)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想在应用程序进入前台时开始记录流程,请像这样使用它:

@Composable
fun MyApp(viewModel: LoginViewModel) {

...
    OnLifecycleEvent { owner, event ->
        when (event) {
            Lifecycle.Event.ON_RESUME -> { viewModel.performLogin(ctx) }
            else -> { ... }
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

我实际上使用了这个问题及其答案作为来源