@Composable
fun BottomNavigationBar(navController: NavHostController) {
val items = listOf(
Screen.Health,
Screen.Move,
Screen.Service,
Screen.Mine
)
val pics_Selected = mapOf(
Screen.Health to R.mipmap.health_orange,
Screen.Move to R.mipmap.move_orange,
Screen.Service to R.mipmap.device_orange,
Screen.Mine to R.mipmap.mine_orange
)
val pics_unselected = mapOf(
Screen.Health to R.mipmap.health_gray,
Screen.Move to R.mipmap.move_gray,
Screen.Service to R.mipmap.device_gray,
Screen.Mine to R.mipmap.mine_gray
)
val pic_unselected = mapOf(
"health" to R.mipmap.health_gray,
"move" to R.mipmap.move_gray,
"service" to R.mipmap.device_gray,
"mine" to R.mipmap.mine_gray
)
val pic_selected = mapOf(
"health" to R.mipmap.health_orange,
"move" to R.mipmap.move_orange,
"service" to R.mipmap.device_orange,
"mine" to R.mipmap.mine_orange
)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
BottomNavigation(
backgroundColor = Color.White,
elevation = 10.dp
) {
items.forEach { screen ->
BottomNavigationItem(
icon = {
val iconResource = if (screen == navController?.currentDestination) {
pic_selected[screen.route] ?: R.mipmap.sleep
}
else {
pic_unselected[screen.route] ?: R.mipmap.sleep
}
Image(painter = painterResource(id = iconResource), contentDescription = null, modifier = Modifier.size(24.dp))
},
label = { Text(stringResource(screen.resourceId)) },
selected = currentRoute == screen.route,
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.startDestinationId)
launchSingleTop = true
}
}
)
}
}
}
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.size
import androidx.compose.material3.BottomNavigation
import androidx.compose.material3.BottomNavigationItem
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
@Composable
fun BottomNavigationBar(navController: NavHostController) {
val items = listOf(
Screen.Health,
Screen.Move,
Screen.Service,
Screen.Mine
)
val pic_unselected = mapOf(
"health" to R.mipmap.health_gray,
"move" to R.mipmap.move_gray,
"service" to R.mipmap.device_gray,
"mine" to R.mipmap.mine_gray
)
val pic_selected = mapOf(
"health" to R.mipmap.health_orange,
"move" to R.mipmap.move_orange,
"service" to R.mipmap.device_orange,
"mine" to R.mipmap.mine_orange
)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
BottomNavigation(
backgroundColor = MaterialTheme.colorScheme.background,
elevation = 10.dp
) {
items.forEach { screen ->
BottomNavigationItem(
icon = {
val iconResource = if (currentRoute == screen.route) {
pic_selected[screen.route] ?: R.mipmap.sleep
} else {
pic_unselected[screen.route] ?: R.mipmap.sleep
}
Image(
painter = painterResource(id = iconResource),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
},
label = { Text(text = screen.route) },
selected = currentRoute == screen.route,
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
遇到的问题
导航栏的图标切换
1.1 screen == navController?.currentDestination 的比较
在第二段代码中,你尝试使用 screen == navController?.currentDestination 来比较当前选中的屏幕。这是不正确的,因为:
修正方法:
你应该比较 screen.route 和 currentRoute,因为它们都是字符串类型,可以直接比较。
1.2 pic_selected 和 pic_unselected 的使用
在第二段代码中,你定义了两组 Map:
在 BottomNavigationItem 中,你尝试使用 pic_selected[screen.route] 和 pic_unselected[screen.route],但这些 Map 的键是 Screen 对象,而不是字符串。这会导致 Map 查找失败,返回 null。
修正方法:
统一使用字符串作为键,或者在查找时正确地使用 Screen 对象作为键。
1.3 label 的内容
在第二段代码中,你使用了 stringResource(screen.resourceId),但 screen.resourceId 并未在 Screen 类中定义。这会导致编译错误。
修正方法:
确保 Screen 类中有一个 resourceId 属性,或者直接使用 screen.route 作为标签内容。
1.4 navController?.currentDestination 的使用
在第二段代码中,你尝试使用 navController?.currentDestination,但这是不正确的。你应该使用 currentRoute 来比较当前选中的屏幕。
修正方法:
直接使用 currentRoute,而不是 navController?.currentDestination。
更改后