Jetpack Compose 底部导航BottomNavigation

对比iOS和flutter,Jetpack Compose的底部导航有自己的特色,更像flutter的底部导航。按照官网提供的方式结合项目实例,完成了小功能的实现:

1.创建好脚手架Scallfold函数和对应的选中图标和未选中标题,以及对应的颜色。

2.创建每个item对应的Composable函数界面

3.配合官网建议,利用密封类和导航来进行底部不同界面的切换

@ExperimentalFoundationApi
@Composable
fun Tab(viewModel: ViewMod){
    // tab标题
    val listItem = listOf("组织","发现","我的")
    // tab未选图标
    val icons = listOf(R.drawable.home,R.drawable.find,R.drawable.profile)
    // tab选中图标
    val selectIcons = listOf(R.drawable.homeselect,R.drawable.findselect,R.drawable.profileselect)
    // 记住选中tab位置
    val selectIndex = remember {
        mutableStateOf(0)
    }
    // 脚手架
    val navControllers = rememberNavController()
    Scaffold(
        modifier = Modifier.fillMaxSize(),
        bottomBar = {
            // BottomNavigation的显示和隐藏先借助本地数据存储,再说
            BottomNavigation(
                backgroundColor = Color.White,
                elevation = 3.dp
            ) {
                val navBackStackEntry by navControllers.currentBackStackEntryAsState()
                val currentRoute = navBackStackEntry?.arguments?.getString(KEY_ROUTE)

                items.forEachIndexed { index, s ->
                    BottomNavigationItem(
                        selected = currentRoute == s.route,
                        onClick = {
                            selectIndex.value = index
                            navControllers.navigate(s.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 = navControllers.graph.startDestination
                                // Avoid multiple copies of the same destination when
                                // reselecting the same item
                                launchSingleTop = true
                            }
                                  },
                        icon = {
                            when(index){
                                selectIndex.value -> {
                                    Image(painter = painterResource(id = selectIcons[index]), contentDescription = null)
                                }
                                else -> {
                                    Image(painter = painterResource(id = icons[index]), contentDescription = null)
                                }
                            }
                        },
                        label = {
                           Text(
                               text = listItem[index],
                               textAlign = TextAlign.Center,
                               color = if (index == selectIndex.value) Color(0xFF0077E6) else Color(0xFFD8D8D8)
                           )
                        }
                    )
                }
            }
        },
        content = {
            NavHost(navControllers, startDestination = Screen.Home.route) {
                // 首页
                composable(Screen.Home.route) { Home(viewModel,navControllers) }
                // 发现
                composable(Screen.Find.route) { Find(navControllers) }
                // 我的
                composable(Screen.Profile.route) { Profile(navControllers,viewModel) }
            }
        }
    )
}

sealed class Screen(val route: String, @StringRes val resourceId: Int) {
    object Home : Screen("home", R.string.home)
    object Find : Screen("find", R.string.find)
    object Profile : Screen("profile", R.string.profile)

}

val items = listOf(
    Screen.Home,
    Screen.Find,
    Screen.Profile
)

之所以用密封类和导航来进行界面的切换,是为了减少界面的重复创建和资源的消耗浪费。比如根据切换的位置进行界面的切换(不建议):

 content = {
            when(selectIndex){
                0 -> Home()
                1 -> Find()
                else -> Profile()
            }

你可能感兴趣的:(Jetpack Compose 底部导航BottomNavigation)