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

djmepvbi  于 2022-11-16  发布在  Kotlin
关注(0)|答案(2)|浏览(140)

我的应用程序使用OpenID对用户进行身份验证。
第一个页面更像是一个闪屏,如果需要的话,用户可以进入一个网页进行授权,或者只是对令牌进行后台刷新,然后导航到主屏幕。
我不确定如何在不单击按钮的情况下启动身份验证流程

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

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

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()
        }
    }
}

我不认为我应该像在Composable函数中那样调用performLogin函数,但我看不到其他方法。我错过了什么?

nnvyjq4y

nnvyjq4y1#

您可以将您的流程与生命周期回调绑定。您可以创建可组合的实用程序来处理生命周期事件。

@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)
        }
    }
}

如果您希望在应用进入前台时启动日志流,请按以下方式使用:

@Composable
fun MyApp(viewModel: LoginViewModel) {

...
    OnLifecycleEvent { owner, event ->
        when (event) {
            Lifecycle.Event.ON_RESUME -> { viewModel.performLogin(ctx) }
            else -> { ... }
       }
    }
}

我实际上使用this question and its answer作为源代码

vom3gejh

vom3gejh2#

您可以使用的另一种方法如下
让我们一步一步来:)
第一步:ViewModel必须实现DefaultLifecycleObserver接口

@HiltViewModel
class LoginViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle
) : ViewModel(), DefaultLifecycleObserver {
}

通过这种方式,您可以访问以下方法:

public interface DefaultLifecycleObserver extends FullLifecycleObserver {

    /**
     * Notifies that {@code ON_CREATE} event occurred.
     * <p>
     * This method will be called after the {@link LifecycleOwner}'s {@code onCreate}
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {
    }

    /**
     * Notifies that {@code ON_START} event occurred.
     * <p>
     * This method will be called after the {@link LifecycleOwner}'s {@code onStart} method returns.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onStart(@NonNull LifecycleOwner owner) {
    }

    /**
     * Notifies that {@code ON_RESUME} event occurred.
     * <p>
     * This method will be called after the {@link LifecycleOwner}'s {@code onResume}
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onResume(@NonNull LifecycleOwner owner) {
    }

    /**
     * Notifies that {@code ON_PAUSE} event occurred.
     * <p>
     * This method will be called before the {@link LifecycleOwner}'s {@code onPause} method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onPause(@NonNull LifecycleOwner owner) {
    }

    /**
     * Notifies that {@code ON_STOP} event occurred.
     * <p>
     * This method will be called before the {@link LifecycleOwner}'s {@code onStop} method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onStop(@NonNull LifecycleOwner owner) {
    }

    /**
     * Notifies that {@code ON_DESTROY} event occurred.
     * <p>
     * This method will be called before the {@link LifecycleOwner}'s {@code onDestroy} method
     * is called.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onDestroy(@NonNull LifecycleOwner owner) {
    }
}

第二步:在您的Composable中,调用我发送给附件的方法,如下所示。
创建如下扩展函数:

@Composable
fun <LO : LifecycleObserver> LO.ObserveLifecycle(lifecycle: Lifecycle) {
  DisposableEffect(lifecycle) {
    lifecycle.addObserver(this@ObserveLifecycle)
    onDispose {
      lifecycle.removeObserver(this@ObserveLifecycle)
    }
  }
}

在可组合函数中调用它,如下所示

@Composable
fun LoginScreen(viewModel: LoginViewModel) {
    viewModel.observeLifecycle(LocalLifecycleOwner.current.lifecycle)
}

口渴步骤:在ViewModel中实现您的逻辑,如果您要转到另一个页面,请通知Composable by Event

LoginViewModel.kt
 override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
 }

相关问题