1

我正在使用适用于 android 12 的新 SplashScreen API,但我现在对登录流程有点困惑。按照 google 的建议,我有一个活动和多个片段,mainActivity 是启动splashScreen 的地方,用户应该被引导到登录片段或主页片段。我的问题是如何使用新的 SplashAPI 实现这个工作流程?startDestination 应该是什么片段?我不想使用 popTo 属性,因为总是显示 loginfragment 然后将用户定向到 Homefragment 看起来并不漂亮。如果有人可以向我解释这一点,我将不胜感激。

4

2 回答 2

0

Homefragment 应该是 startDestination。有条件地导航到 loginfragment 并在身份验证后弹回 Homefragment。请参阅 Ian Lake 的以下视频。
https://www.youtube.com/watch?v=09qjn706ITA

于 2022-02-17T11:02:44.417 回答
0

我有一个解决方法,您可以在检查用户是否获得授权并将用户状态保存在 ViewModel 或其他内容后设置活动的内容,然后在此状态下设置您的内容。

我利用图书馆的setKeepOnScreenCondition功能力量。core-splashscreen

SplashInstaller.kt

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        SplashInstaller(
            activity = this,
            beforeHide = {
                // Check if logged in or not asyncrounsly
                delay(2000)
            },
            afterHide = {
                setContent()
                // start with you desired destination up on the check you did in beforeHide
            })
    }
/**
 * @author Mohamed Elshaarawy on Oct 14, 2021.
 */
class SplashInstaller<A : ComponentActivity>(
    private val activity: A,
    visibilityPredicate: () -> Boolean = { BuildConfig.BUILD_TYPE != "debug" },
    private val beforeHide: suspend A.() -> Unit = { delay(2000) },
    private val afterHide: A.() -> Unit
) : CoroutineScope by activity.lifecycleScope {

    private val isSplashVisibleChannel by lazy { Channel<Boolean>() }

    private val isAfterCalled by lazy { Channel<Boolean>(capacity = 1) }

    private val splashSuspensionJob = launch(start = CoroutineStart.LAZY) {
        activity.beforeHide()
        isSplashVisibleChannel.send(false)
    }

    init {
        if (visibilityPredicate()) {
            splashSuspensionJob.start()
            installSplash()
        } else afterSplash()
    }

    private fun installSplash() {
        activity.installSplashScreen().setKeepOnScreenCondition {
            val isVisible = isSplashVisibleChannel.tryReceive().getOrNull() ?: true
            if (!isVisible) {
                afterSplash()
            }
            isVisible
        }
    }

    private fun afterSplash() {
        if (isAfterCalled.tryReceive().getOrNull() != true) {
            isAfterCalled.trySend(true)
            activity.afterHide()
        }
    }
}

该解决方案使用

androidx.core:core-splashscreen:1.0.0-beta01

androidx.lifecycle:lifecycle-runtime-ktx:2.4.0

org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2

于 2022-02-17T14:47:24.017 回答