0

我想使用基于 NavigationBar 中选定状态的轮廓和填充图标,就像谷歌地图应用程序一样,使用 jetpack compose。在 xml 的情况下,我们使用选择器,那么我们在 compose 中使用什么?

这是我的代码->

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()
}

屏幕.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()
}

我还需要使用选择器 xml 还是在 jetpack compose 中有替代方法?

4

1 回答 1

1

是的,您只需根据selected状态创建一个简单的 if 语句,如下所示:

items.forEach { screen ->
    val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true
    NavigationBarItem(
        icon = {
            Icon(
                if (selected) screen.icon_filled else screen.icon_outlined,
                contentDescription = screen.label.toString()
            )
        },
        selected = selected,
    )
}
于 2022-01-24T21:36:11.903 回答