I have a app using Jetpack Compose.
I have two screens:
1. NewsScreen
2. SettingsScreen
The default is NewsScreen.
I have a NavHost
called AppNavigation.kt
:
@Composable
fun AppNavigation() {
val navController = rememberNavController()
val settingsViewModel: SettingsViewModel = viewModel()
NavHost(
navController = navController,
startDestination = AppScreens.NewsScreen.name
) {
composable(AppScreens.NewsScreen.name) {
NewsScreen(navController = navController, settingsViewModel)
}
composable(AppScreens.SettingsScreen.name) {
SettingsScreen(navController = navController, settingsViewModel)
}
}
}
And also enum class:
enum class AppScreens {
NewsScreen,
SettingsScreen;
companion object {
fun fromRoute(route: String): AppScreens
= when (route?.substringBefore("/")) {
NewsScreen.name -> NewsScreen
SettingsScreen.name -> SettingsScreen
else -> throw IllegalArgumentException("Unknown route: $route")
}
}
}
My Scaffold looks like this in HomePage.kt
:
@Composable
fun HomeScreen(navController: NavController, settingsViewModel: SettingsViewModel) {
val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
Scaffold(
Modifier.background(Color.Transparent),
scaffoldState = scaffoldState,
drawerContent = {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
Card(
modifier = Modifier.padding(vertical = 15.dp),
shape = RoundedCornerShape(15.dp, 0.dp, 0.dp, 15.dp),
) {
Column(
modifier = Modifier.fillMaxHeight(),
verticalArrangement = Arrangement.SpaceBetween
) {
/* ... */
}
}
}
},
bottomBar = {
BottomAppNavigationBar(navController = navController)
},
floatingActionButton = {
FloatingActionButton(
backgroundColor = Color.White,
modifier = Modifier.size(75.dp),
onClick = { /* ... */ }
) {
/* FAB content */
}
},
floatingActionButtonPosition = FabPosition.Center,
isFloatingActionButtonDocked = true,
)
{ contentPadding ->
// Screen content
Box(
modifier = Modifier
.padding(contentPadding)
.background(
Color("#C8DBE2".toColorInt())
)
) {
TopAppBar(
modifier = Modifier.padding(20.dp, 10.dp),
backgroundColor = Color.Transparent,
elevation = 0.dp
) {
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
NavMenuButton(scope, scaffoldState)
ProfileMenuButton()
}
}
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
NewsScreen(navController = navController)
}
}
}
}
And finally, BottomAppNavigationBar
@Composable
fun BottomAppNavigationBar(navController: NavController) {
val navTextList = listOf(
AppScreens.NewsScreen.name,
AppScreens.SettingsScreen.name,
)
var selectIndex by remember { mutableStateOf(0) }
val iconList = listOf(
painterResource(id = R.drawable.news),
painterResource(id = R.drawable.settings),
)
BottomAppBar(
// Defaults to null, that is, No cutout
cutoutShape = MaterialTheme.shapes.small.copy(
CornerSize(percent = 50)
),
backgroundColor = Color.Transparent,
elevation = 90.dp,
modifier = Modifier
.height(80.dp)
.fillMaxWidth()
.shadow(50.dp)
.clip(
(RoundedCornerShape(15.dp, 15.dp, 0.dp, 0.dp))
)
) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(top = 5.dp)
.background(Color.Transparent),
shape = RoundedCornerShape(15.dp, 15.dp, 0.dp, 0.dp),
) {
Row(
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier.fillMaxWidth()
) {
navTextList.forEachIndexed { index, str ->
BottomNavigationItem(
label = { Text(str) },
selected = index == selectIndex,
modifier = Modifier.background(Color.White),
selectedContentColor = Color.LightGray,
unselectedContentColor = Color.Gray,
onClick = {
navController.navigate(str) {
navController.graph.startDestinationRoute?.let { screen_route ->
popUpTo(screen_route) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}
},
icon = {
Icon(
modifier = Modifier
.size(47.dp)
.padding(top = 15.dp),
tint = Color.Black,
painter = iconList[index],
contentDescription = null
)
})
if (index == 0) {
Spacer(modifier = Modifier.size(90.dp))
}
}
}
}
}
}
How do I make it change to all NewsScreen and SettingsScreen when clicking bottom nav bar?