Alex20280
Alex20280

Reputation: 355

How to combine swipable bottom bar and Compose navigation?

I have a Compose app with bottom navigation. In total, the navigation works fine. But I need to integrate horizontal swipe so that the bottom tab can switch when I swipe screens. But I have problems with it. I tried to Google but nothing helped.

Tried to make a horizontal Pager but the problem is that it doesn't accept composables inside of it.

   val screens = listOf(
        Screens.NewsScreen,
        Screens.SourceScreen,
        Screens.SavedScreen,
    )

    val navController = rememberNavController()

    Scaffold(
        bottomBar = {
            if (bottomBarVisible) {
                BottomNavigationSection(navController = navController, items = screens, sharedScreenViewModel = sharedScreenViewModel)
            }
        },
    ) {

       NavigationGraph(navController = navController, paddingValues = it, sharedScreenViewModel = sharedScreenViewModel)
    }
  

@Composable
fun BottomNavigationSection(
    navController: NavHostController,
    items: List<Screens>,
    sharedScreenViewModel: SharedScreenViewModel
) {
    BottomNavigation {

        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentRoute = navBackStackEntry?.destination?.route
        val sourceState = sharedScreenViewModel.uiState.collectAsState()

        items.forEach { screen ->
            BottomNavigationItem(
                modifier = Modifier
                    .background(colorResource(id = R.color.grey))
                    .fillMaxSize(),
                icon = {
                    Icon(
                        painter = painterResource(id = screen.icon),
                        contentDescription = null
                    )
                },
                selected = currentRoute == screen.route,
                onClick = {
                    navController.navigate(screen.route) {
                        popUpTo(navController.graph.findStartDestination().id) {
                            saveState = true
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                },
                alwaysShowLabel = false,
                selectedContentColor = colorResource(id = R.color.yellow),
                unselectedContentColor = colorResource(id = R.color.white)
            )
        }
    }
}

@Composable
fun NavigationGraph(
    navController: NavHostController,
    paddingValues: PaddingValues,
    sharedScreenViewModel: SharedScreenViewModel,
) {

    NavHost(navController = navController, startDestination = Screens.NewsScreen.route) {

       composable(
            route = "news/{source}",
            arguments = listOf(
                navArgument("source") {
                    type = NavType.StringType
                    defaultValue = ""
                }
            )
        ) { backStackEntry ->
           val source = backStackEntry.arguments?.getString("source") ?: "nullsource"
            sharedScreenViewModel.setSource(source)
            NewsScreen(source = source, viewModel = sharedScreenViewModel, navController = navController, paddingValues = paddingValues)
        }

       composable(Screens.SourceScreen.route) {
            SourceScreen(viewModel = sharedScreenViewModel)
        }

        composable(Screens.SavedScreen.route) {
            SavedNewsScreen(
                viewModel = sharedScreenViewModel,
                navController = navController
            )
        }

        composable(
            route = Screens.DetailsScreen.getRouteWithParams("{itemId}"),
            arguments = listOf(
                navArgument("itemId") {
                    type = NavType.IntType
                    defaultValue = 0
                }
            )
        ) { backStackEntry ->
            //val itemId = backStackEntry.arguments!!.getInt("itemId")
            DetailsScreen(
                navController = navController
            )
        }

        composable(
            route = "webview?url={url}",
            arguments = listOf(
                navArgument("url") {
                    type = NavType.StringType
                }
            )
        ) { backStackEntry ->
            val url = backStackEntry.arguments?.getString("url")
            ChromeCustomTab(url = url)
        }
    }

}

enter image description here

Upvotes: 1

Views: 259

Answers (0)

Related Questions