I want to use outlined and filled icons based on selected state in NavigationBar just like google maps app, using jetpack compose. In case of xml we use selector so what do we use for compose ?
Here is my code ->
MainActivity.kt
@ExperimentalMaterial3Api
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Handle the splash screen transition.
installSplashScreen()
setContent {
MyApp()
}
}
}
@ExperimentalMaterial3Api
@Composable
fun MyApp() {
MyTheme {
val items = listOf(
Screen.HomeScreen,
Screen.MusicScreen,
Screen.ProfileScreen
)
val navController = rememberNavController()
Scaffold(
bottomBar = {
NavigationBar {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach { screen ->
NavigationBarItem(
icon = {
Icon(
screen.icon_outlined,
contentDescription = screen.label.toString()
)
},
label = { Text(stringResource(screen.label)) },
selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
onClick = {
navController.navigate(screen.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
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
}
}
)
}
}
}
) { innerPadding ->
NavHost(
navController,
startDestination = Screen.HomeScreen.route,
Modifier.padding(innerPadding)
) {
composable(route = Screen.HomeScreen.route) {
HomeScreen()
}
composable(route = Screen.MusicScreen.route) {
MusicScreen()
}
composable(route = Screen.ProfileScreen.route) {
ProfileScreen()
}
}
}
}
}
@ExperimentalMaterial3Api
@Preview(
showBackground = true, name = "Light mode",
uiMode = Configuration.UI_MODE_NIGHT_NO or Configuration.UI_MODE_TYPE_NORMAL
)
@Preview(
showBackground = true, name = "Night mode",
uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL
)
@Composable
fun DefaultPreview() {
MyApp()
}
Screen.kt
sealed class Screen(
val route: String,
@StringRes val label: Int,
val icon_outlined: ImageVector,
val icon_filled: ImageVector
) {
object HomeScreen : Screen(
route = "home_screen",
label = R.string.home,
icon_outlined = Icons.Outlined.Home,
icon_filled = Icons.Filled.Home
)
object MusicScreen : Screen(
route = "music_screen",
label = R.string.music,
icon_outlined = Icons.Outlined.LibraryMusic,
icon_filled = Icons.Filled.LibraryMusic,
)
object ProfileScreen : Screen(
route = "profile_screen",
label = R.string.profile,
icon_outlined = Icons.Outlined.AccountCircle,
icon_filled = Icons.Filled.AccountCircle,
)
}
HomeScreen.kt
@Composable
fun HomeScreen() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Surface(color = MaterialTheme.colorScheme.background) {
Text(
text = "Home",
color = Color.Red,
fontSize = MaterialTheme.typography.displayLarge.fontSize,
fontWeight = FontWeight.Bold
)
}
}
}
@Preview(
showBackground = true, name = "Light mode",
uiMode = Configuration.UI_MODE_NIGHT_NO or Configuration.UI_MODE_TYPE_NORMAL
)
@Preview(
showBackground = true, name = "Night mode",
uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL
)
@Composable
fun HomeScreenPreview() {
HomeScreen()
}
Do I still need to use selector xml or there is alternative way in jetpack compose?
if
? Something likeif (selected) screen.icon_outlined else screen.icon_filled
– Kobi