如何在喷气背包导航中不显示目的地?

问题描述 投票:0回答:1

我有这些屏幕:

NavHost(
    navController = navController,
    startDestination = AuthScreen.route
) {
    composable(
        route = AuthScreen.route
    ) {
        AuthScreen()
    }
    composable(
        route = MainScreen.route
    ) {
        MainScreen()
    }
}

在MainActivity中,我需要根据身份验证状态将用户发送到正确的屏幕。所以我用:

val isUserSignedOut = viewModel.getAuthState().collectAsState().value
if (isUserSignedOut) {
    navController.navigate(AuthScreen.route) {
        popUpTo(navController.graph.id) {
            inclusive = true
        }
    }
} else {
    navController.navigate(MainScreen.route) {
        popUpTo(navController.graph.id) {
            inclusive = true
        }
    }
}

一切都按预期进行,因为我认为这是一个同步操作。现在,当用户通过身份验证时,我需要创建一个请求来检查用户的类型。这是我尝试过的:

if (isUserSignedOut) {
    navController.navigate(AuthScreen.route) {
        popUpTo(navController.graph.id) {
            inclusive = true
        }
    }
} else {
    Request(
        checkAdmin = { admin ->
            if (admin) {
                navController.navigate(AdminScreen.route) {
                    popUpTo(navController.graph.id) {
                        inclusive = true
                    }
                }
            } else {
                navController.navigate(MainScreen.route) {
                    popUpTo(navController.graph.id) {
                        inclusive = true
                    }
                }
            }
        }
    )
}

此代码的问题是,当我打开应用程序时,即使用户已通过身份验证,我第一次也会显示

AuthScreen
。换句话说,当我收到异步请求的响应时,会显示
AuthScreen
,但我不希望这样。我需要先转到
MainScreen
AdminScreen
,而不显示
AuthScreen
。怎么解决这个问题?

android kotlin android-jetpack-compose android-jetpack android-jetpack-navigation
1个回答
0
投票

您可能这样声明

isUserSignedOut

var isUserSignedOut by remember { mutableStateOf(true) }

这会将变量初始化为 true。这将导致立即显示 AuthScreen。

你必须引入第三种状态:

  • 加载中
  • 用户已登录
  • 用户未登录

当App执行异步请求时,将状态设置为“正在加载”,然后显示一个正在加载的Composable。

您必须选择执行此操作:

A) 您可以创建第二个布尔变量:

var isLoading by remember { mutableStateOf(true) }

然后将您的条件更新为

if (isLoading) {
    // show or navigate to Loading Screen Composable
} else if (isUserSignedOut) {
    navController.navigate(AuthScreen.route) {
        popUpTo(navController.graph.id) {
            inclusive = true
        }
    }
} else {
    Request(
        checkAdmin = { admin ->
            if (admin) {
                navController.navigate(AdminScreen.route) {
                    popUpTo(navController.graph.id) {
                        inclusive = true
                    }
                }
            } else {
                navController.navigate(MainScreen.route) {
                    popUpTo(navController.graph.id) {
                        inclusive = true
                    }
                }
            }
        }
    )
}

异步操作完成后,执行

isLoading = false

B) 您可以创建一个枚举来表示不同的状态:

enum class UIState{
    LOADING, LOGGEDIN, NOTLOGGEDIN
}

在您的可组合项中:

var uiState by remember { mutableStateOf(UISTATE.LOADING) }

if (uiState.equals(UIState.LOADING) {
    //...
} else if (uiState.equals(UIState.NOTLOGGEDIN) {
    //...
} else {
   //...
}
© www.soinside.com 2019 - 2024. All rights reserved.