简体   繁体   English

当用户第二次使用 Jetpack Compose with Flow 打开应用程序时,跳过 NavHost 中的登录页面

[英]Skip landing page in NavHost when user opens the app for second time using Jetpack Compose with Flow

I have an app with HorizontalPager at startDestination screen and after I go to the last page, the app shows the home page.我在 startDestination 屏幕上有一个带有HorizontalPager ntalPager 的应用程序,在我 go 到最后一页后,该应用程序显示主页。 When I open the app for second time it should show Home page immediately and never again show that startDestination screen with HorizontalPager .当我第二次打开该应用程序时,它应该立即显示主页,并且不再显示带有HorizontalPager ntalPager 的 startDestination 屏幕。 I used dataStore and it works, but the problem is that every time I open the app it flashes for a second that HorizontalPager landing page and then it switches to the home page.我使用了dataStore,它可以工作,但问题是每次我打开应用程序时,Horizo HorizontalPager登陆页面都会闪烁一秒钟,然后切换到主页。 I used flow to get true/false state of the app start, so it will know it will know app was already opened for first time.我使用流来获取应用程序启动的真/假 state,所以它会知道它会知道应用程序已经第一次打开。

class MainActivity : ComponentActivity() {
    @ExperimentalAnimationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            WebSafeTheme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    val navController = rememberNavController()
                    Navigation(navController)
                }
            }
        }
    }
}

@ExperimentalAnimationApi
@ExperimentalMaterialApi
@ExperimentalFoundationApi
@ExperimentalPagerApi
@Composable
fun Navigation(
    navController: NavHostController
    ) {
    val context = LocalContext.current
    val preferencesManager = PreferencesManager(context)
    val preferencesFlow = preferencesManager.preferencesFlow
    val scope = rememberCoroutineScope()
    val result = remember { mutableStateOf(Constants.SKIP_LANDING_PAGE) }
    scope.launch {
        result.value = preferencesFlow.first().skipLandingPage
    }

    NavHost(
        navController = navController,
//it goes it this line 2 times, first time when the app opens and second time after the flow is finished
        startDestination = if (result.value) Screen.HomeScreen.route else Screen.LandingScreen.route,
        modifier = Modifier.fillMaxSize()
    ) {
        composable(
            route = Screen.LandingScreen.route
        ) {
            Landing(navController)
        }
        composable(
            route = Screen.SkipChooseCountryScreen.route
        ) {
            ChooseCountry()
        }
        composable(
            route = Screen.HomeScreen.route
        ) {
            Home(navController)
        }
    }
}

It goes to NavHost for the first time after app openes and it always returns FALSE as it is default value, after that flow returns TRUE(so it knows app was opened at least once before) and then it openes the correct screen.它在应用程序打开后第一次进入 NavHost,它总是返回 FALSE,因为它是默认值,在该流程返回 TRUE 之后(因此它知道应用程序之前至少打开过一次),然后它打开正确的屏幕。

I have no idea how to make NavHost to wait that flow to finishes.我不知道如何让 NavHost 等待该流程完成。 I tried to put NavHost into the scope but it didn't allow me.我试图将 NavHost 放入 scope 但它不允许我。

I also need to read data from data store, so this is how I do it:我还需要从数据存储中读取数据,所以我是这样做的:

Crossfade(
    targetState = state.value.loadState
) { loadState ->
    when (loadState) {
        LoadState.NOT_LOADED -> Box(modifier = Modifier.fillMaxSize())
        LoadState.SHOW_PIN -> PinScreen(
            loadState = loadState,
            state = state,
            modifier = Modifier.fillMaxSize(),
        )
        LoadState.SHOW_CONTENT -> MainContent(
            state = state,
        )
    }
}

Initially my state is NOT_LOADED so I just display an empty box that fills the screen.最初我的 state 是NOT_LOADED所以我只显示一个填满屏幕的空框。 You could alternatively display a spinner, or your app's logo.您也可以显示微调器或应用程序的徽标。 Once the data has been loaded, I show the PIN screen if the user has PIN enabled, or the main screen otherwise.加载数据后,如果用户启用了 PIN,我将显示 PIN 屏幕,否则显示主屏幕。

Also, note that you should not have your viewpager screen as your root destination, your home page should be your root destination, and you should conditionally navigate to the viewpager if the user has not seen your onboarding flow yet.另外,请注意,您不应该将您的浏览器屏幕作为您的根目的地,您的主页应该是您的根目的地,并且如果用户还没有看到您的入职流程,您应该有条件地导航到浏览器。 Check this for details.检查以获取详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Jetpack 使用 Fragments 编写 NavHost - Jetpack Compose NavHost with Fragments 在jetpack compose中为navHost添加bottomNavigation - Add bottomNavigation for navHost in jetpack compose 在 Jetpack Compose (NavHost) 中使用 Nested Navigation 时如何获取我来自哪条主要路线 - How can I obtain from which Main Route I came from when using Nested Navigation in Jetpack Compose (NavHost) Jetpack compose NavHost 防止重新组合屏幕 - Jetpack compose NavHost prevent recomposition screens Jetpack Compose NavHost 重组可多次组合 - Jetpack Compose NavHost recomposition composable multiple times 在 Jetpack Compose 中打开抽屉时推送内容 - Push content when drawer opens in Jetpack Compose 在没有 Flow 的情况下使用 Jetpack Compose Paging 库 - Using Jetpack Compose Paging library without Flow 如何在 Jetpack Compose 中从一个 NavHost 向上导航到另一个? - How to navigate up from one NavHost to another in Jetpack Compose? 在 Android 应用程序中使用 Jetpack compose 时如何禁用 Darktheme? - How to disable Darktheme when using Jetpack compose in Android app? Jetpack Compose:拖动 MapView 时打开脚手架抽屉 - Jetpack Compose: Scaffold drawer opens when dragging MapView
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM