Reputation: 180
I want to navigate from Screen-A(SplashScreen
) to Screen-B(Having BottomNavigation
containing 3 screens say HomeScreen
, SearchScreen
and ProfileScreen
) and from bottomnavigation
screen(i.e Screen-B) to another Screen(from home screen to detail screen without bottomnavBar
)
I am not able to do this as in official docs there was simple explanation for this.
Here is the code i have done so far
This is my main activity class
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
My_grocery_app_composeTheme {
MyApp()
}
}
}
}
@Composable
fun MyApp() {
val navController = rememberNavController()
SetupNavGraph(navController = navController)
}
This is my navGraph
@Composable
fun SetupNavGraph(navController: NavHostController) {
NavHost(
navController = navController,
route = ROOT_GRAPH_ROUTE,
startDestination = Initial_Setup_Route
) {
initialSetupNavGraph(navController)
bottomNavigationNavGraph(navController)
}
}
fun NavGraphBuilder.initialSetupNavGraph(navController: NavController) {
navigation(startDestination = Screen.Splash.route, route = Initial_Setup_Route) {
composable(Screen.Splash.route) {
SplashScreen(navController = navController)
}
composable(Screen.BottomNavigation.route) {
BottomNavScreen(navController = navController)
}
composable(Screen.Other.route) {
OtherScreen()
}
}
}
//
fun NavGraphBuilder.bottomNavigationNavGraph(navController: NavController) {
navigation(startDestination = Screen.Home.route, route = BottomNavigation_Route) {
composable(Screen.Home.route) {
HomeScreen()
}
composable(Screen.Search.route) {
SearchScreen()
}
composable(Screen.Cart.route) {
CartScreen()
}
composable(Screen.History.route) {
HistoryScreen()
}
composable(Screen.Profile.route) {
ProfileScreen()
}
}
}
This is my SplashScreen
@Composable
fun SplashScreen(navController: NavController) {
LaunchedEffect(key1 = true,){
delay(3000L)
navController.navigate(Screen.BottomNavigation.route)
}
Scaffold {
Text(
"Splash Screen", style = MaterialTheme.typography.h4
)
}
}
This is my bottomNavScreen
var navItems = listOf<NavItem>(
NavItem(label = "Home", route = "home_screen", icon = Icons.Default.Home),
NavItem(label = "Search", route = "search_screen", icon = Icons.Default.Search),
NavItem(label = "Cart", route = "cart_screen", icon = Icons.Default.ShoppingBag),
NavItem(label = "History", route = "history_screen", icon = Icons.Default.Notes),
NavItem(label = "Profile", route = "profile_screen", icon = Icons.Default.Person),
)
@Composable
fun BottomNavScreen(navController: NavController) {
val nnaa = rememberNavController()
Scaffold(
backgroundColor = Color.LightGray,
bottomBar = {
CustomBottomNavBar(items = navItems, navController = navController) {
navController.navigate(it.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
}
}
) {
//What to add here
}
}
Upvotes: 2
Views: 1153
Reputation: 806
I also faced the same issue, after splash screen I was not able to navigate using navcontroller. Instead of using multiple NavHost I fixed it by using the MutableStateFlow for selected bottomNavItem in Viewmodel for Main screen. Further screens navigation from Inner Views of MainScreen can be handled by using Nested Navigation graphs.
@Composable
fun MainScreen(vm: MainViewModel, navControllerRoot: NavHostController) {
val bottomBarItems = listOf(
BottomBarItem.Home,
BottomBarItem.Music,
BottomBarItem.Movies,
BottomBarItem.Profile,
)
val tabRouteState = vm.currentRouteFlow.collectAsState()
Scaffold(
topBar = { ComposeTestTopBar() },
bottomBar = {
ComposeTestBottomBar(
defaultSelected = BottomBarItem.Home,
items = bottomBarItems,
onItemTapped = { v -> vm.currentRoute.value = v.route })
}
) {
MainBody(tabRouteState.value)
}
}
@Composable
fun MainBody(currentRoute: ComposeTestRoute) {
when (currentRoute.toString()) {
ComposeTestRoute.HomeRoute.toString() -> HomeScreen(title = "HOME")
ComposeTestRoute.MusicRoute.toString() -> MusicScreen(title = "MUSIC")
ComposeTestRoute.MovieRoute.toString() -> MovieScreen(title = "MOVIES")
ComposeTestRoute.ProfileRoute.toString() -> ProfileScreen(title = "PROFILE")
else -> CircularProgressIndicator()
}
}
@Composable
fun ComposeTestTopBar() {
TopAppBar(title = { Text(text = stringResource(R.string.app_name)) })
}
Upvotes: 1