BottomNavigationBar 中的 Jetpack Compose 导航问题
Posted
技术标签:
【中文标题】BottomNavigationBar 中的 Jetpack Compose 导航问题【英文标题】:Problem with Jetpack Compose Navigation in BottomNavigationBar 【发布时间】:2021-10-13 06:37:58 【问题描述】:根据下图,我的 App 目前包含 2 个主要路由:Auth 和 Dashboard。当用户启动应用程序时,观察者将检查用户是否已登录并引导他/她到登录页面/仪表板。
Navigation Flow
如您所见,我在 MainActivity 中设置了 NavGraph(包括所有 Dashboard 路由)。问题是当用户单击底部导航项之一时,他/她将被直接引导到视图页面。相反,我想要向用户展示仪表板的脚手架内容内的视图。检查下图。
Problem Encountered
根据信息,一旦用户单击项目,我如何才能在脚手架内容中获取可组合视图?
任何指导将不胜感激。谢谢!
旁注:这是我的第一个撰写项目,我正在尝试在不使用任何片段的情况下实现单活动架构。如果我的代码违反了任何设计或编程约定,我先道歉,因为我对编程很陌生[这里是自学者又名爱好者:( ]。
MainActivity.kt
package com.example.firstcomposeproject
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navigation
import com.example.firstcomposeproject.authview.FirebaseUserViewModel
import com.example.firstcomposeproject.authview.LogIn
import com.example.firstcomposeproject.authview.SignUpFragment
import com.example.firstcomposeproject.dashboard.*
import com.example.firstcomposeproject.ui.theme.FirstComposeProjectTheme
class MainActivity : ComponentActivity()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
val userViewModel: FirebaseUserViewModel by viewModels()
setContent
FirstComposeProjectTheme(
darkTheme = false
)
val navController = rememberNavController()
/*
Observing FirebaseUser LiveData to check if user is logged in. If yes, direct user
to dashboard, else direct user to authenticate screen.
*/
userViewModel.userMutableLiveData.observe(this,
firebaseUser ->
if(firebaseUser != null)
navController.popBackStack()
navController.navigate("dashboard")
popUpTo("auth")
inclusive = true
userViewModel.clearFormField()
else
navController.navigate("auth")
popUpTo("dashboard")
inclusive = true
)
//Navigation Graph For The Whole App
NavHost(navController = navController, startDestination = "auth")
navigation(startDestination = "logInUI", route = "auth")
composable("logInUI")
LogIn(
userViewModel,
onNavigate =
navigateTo(it, navController)
).FinalView()
composable("signUpUI")
SignUpFragment(
userViewModel,
onNavigate =
navigateTo(it, navController)
).FinalView()
addDashBoardGraph(userViewModel, navController)
private fun navigateTo(
dest: String,
navController: NavController
)
navController.navigate(dest)
Dashboard.kt
package com.example.firstcomposeproject.dashboard
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.navigation
import com.example.firstcomposeproject.authview.FirebaseUserViewModel
import com.example.firstcomposeproject.dashboard.helper.Screen
import com.example.firstcomposeproject.ui.theme.Teal200
fun NavGraphBuilder.addDashBoardGraph(
userViewModel: FirebaseUserViewModel,
navController: NavHostController
)
navigation(startDestination = "dashboardUI", route = "dashboard")
composable("dashboardUI")
Dashboard(
navController,
userViewModel
)
composable("navigationUI")
Navigation()
composable("messageUI")
Message()
composable("historyUI")
History()
composable("profileUI")
Profile(
userViewModel
)
@Composable
fun Dashboard(
navController: NavHostController,
userViewModel: FirebaseUserViewModel
)
val items = listOf(
Screen.Navigation,
Screen.Message,
Screen.History,
Screen.Profile
)
Scaffold(
bottomBar =
BottomNavigation(
backgroundColor = Color.White,
contentColor = Teal200
)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach screen ->
BottomNavigationItem(
label = Text(text = screen.label),
selected = currentDestination?.hierarchy?.any it.route == screen.route == true,
onClick =
navController.navigate(screen.route)
popUpTo(navController.graph.findStartDestination().id)
saveState = true
launchSingleTop = true
restoreState = true
,
icon =
Icon(painterResource(id = screen.icon), screen.label)
, unselectedContentColor = Color.Gray
)
)
//Scaffold Content - How to access the compose function from the MainActivity NavGraph here?
【问题讨论】:
检查Nested navigation @VygintasB 如果没记错的话,我已经使用 addDashBoardGraph func 在 NavGraph 中实现了嵌套导航 @EverDream 你找到解决方案了吗? 【参考方案1】:查看您的代码,我认为您需要在 Dashboard 函数的Scaffold
内容中设置一个NavHost
,以告诉系统您要使用您创建的bottomBar
在布局内切换可组合项。
我看到你已经了解nested navigation,所以如果你只想重用相同的NavHost
,你可以尝试在特定的可组合函数中定义它。
@Composable
fun MyNavGraph(
navController: NavHostController = rememberNavController(),
userViewModel: FirebaseUserViewModel
)
NavHost(navController = navController, startDestination = "auth")
navigation(startDestination = "logInUI", route = "auth")
composable("logInUI")
LogIn(
userViewModel,
onNavigate =
navigateTo(it, navController)
).FinalView()
composable("signUpUI")
SignUpFragment(
userViewModel,
onNavigate =
navigateTo(it, navController)
).FinalView()
addDashBoardGraph(userViewModel, navController)
我没有尝试过,如果适合您的情况,请告诉我。 希望对您有所帮助。
【讨论】:
以上是关于BottomNavigationBar 中的 Jetpack Compose 导航问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在BLOC的Flutter中设置BottomNavigationBar中的currentIndex?
BottomNavigationBar 中的 Jetpack Compose 导航问题
Flutter基础组件08BottomNavigationBar
Flutter基础组件08BottomNavigationBar