Jetpack:020-Jetpack导航示例:底部导航栏


我们在上一章回中介绍了Jetpack中导航相关的内容,本章回中主要介绍 导航的综合示例:底部导航栏。闲话休提,让我们一起Talk Android Jetpack吧!

1. 概念介绍

我们在前面章回中介绍过底部导航栏的知识,如果有看官忘记的话可以点击这里查看之前的文章,本章回在此基础上添加导航功能。也就是说点击不同的底部导航标签切换到不同的页面。

回想一下,我们在使用Fragment和Activity实现底部导航时的做法:创建一个Activity并且在Activity中包含Fragment容器,通过Fragment容器来切换Fragment,进而实现底部导航功能。大家看完本章回的内容后就回来对比一下哪种方式的导航方便一些。

2. 使用方法

创建底部导航的方法和在compose中使用Navigation库实现导航的方法类似,下面是详细的使用步骤:

  • 创建NavController;
  • 创建NavHost,并且把各个页面添加到容器中;
  • 通过NavController的navigate方法实现各个页面之间的导航;

3. 代码与分析

3.1 示例代码

介绍完创建底部导航的方法后,我们通过具体的示例代码来演示:

fun ExScaffold(
) {

    //这个NavController主要用来切换底部的导航,只能在这里获取,不能在底部导航的方法中获取,不会导航栏会出现在屏幕上方
    val  naviController = rememberNavController()

    Scaffold(
        modifier = Modifier.background(color = MaterialTheme.colorScheme.primary),
        topBar = { CustomCenterAppBar()},

        bottomBar = { BottomNaviBarTemplate(navController = naviController)},

        //控制FAB的位置,只有两种
        floatingActionButtonPosition = FabPosition.End,
        floatingActionButton = { CustomFAB(snackbarHostState, scope) },
    ) {innerPadding->
        Column(modifier = Modifier
            .padding(innerPadding)
            .fillMaxSize()
            .background(color = CusColor)
        ) {
            Text(text = "hello")
        }

        //这个是自定义的页面配合自定义的底部导航栏使用:CustomBottomNavigationBar
        //这个navHost容器是配合BottomNaviBarTemplate使用的,可以当作代码模板
        NavHost(
            navController = naviController,
            startDestination = BottomNaviScreen.HomeScreen.route,
            modifier = Modifier.padding(innerPadding),
        ) {
            composable(BottomNaviScreen.PersonScreen.route) { PersonScreen(naviController)}
            composable(BottomNaviScreen.HomeScreen.route) { HomeScreen(naviController) }
            composable(BottomNaviScreen.SettingScreen.route) { SettingScreen(naviController) }
        }
    }
}

//参考官方文档编写,compose中习惯把页面叫screen,而在Flutter中习惯叫page,因此在代码中screen和page的含义相同
sealed class BottomNaviScreen(val route:String, val resourceId:Int,val icon:ImageVector) {
    object PersonScreen : BottomNaviScreen("person", R.string.navi_person,Icons.Default.Person)
    object HomeScreen : BottomNaviScreen("home",R.string.navi_home,Icons.Default.Home)
    object SettingScreen: BottomNaviScreen("setting",R.string.navi_setting,Icons.Default.Settings)
}

//创建底部导航栏的模板代码
@Composable
fun BottomNaviBarTemplate(navController: NavController) {
    val screens = listOf(
        BottomNaviScreen.PersonScreen,
        BottomNaviScreen.HomeScreen,
        BottomNaviScreen.SettingScreen,
    )

    NavigationBar(
        containerColor = Color.Blue,
        contentColor = Color.Green, //这个颜色不起作用
    ) {
        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentDestination = navBackStackEntry?.destination

        screens.forEach { item ->
            NavigationBarItem(
                icon = { Icon(imageVector = item.icon, contentDescription = null)},
                label = { Text(text = stringResource(id = item.resourceId))},
                selected = currentDestination?.hierarchy?.any{it.route == item.route} == true,
                onClick = {
                    navController.navigate(item.route) {
                        //popup 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.startDestinationId) {
                            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
                    }
                },
                //设置bar的各种颜色
                colors = NavigationBarItemDefaults.colors(
                    selectedIconColor = Color.Cyan,
                    selectedTextColor = Color.Cyan,
                    //这个颜色最好和NavigationBar的containerColor颜色保持一致,不然会在Icon外层显示一个背景颜色
                    indicatorColor = Color.Blue,
                    unselectedIconColor = Color.Yellow,
                    unselectedTextColor = Color.Yellow,
                ),
            )
        }
    }
}

3.2 代码分析

我们在上面的代码中添加了注释,这样方便大家理解代码,不过还有细节还需要说明:底部导航是通过Scaffold可组合函数实现的,Scaffold函数提供了槽位,我们只需要把底部导航放到槽位中就可以,同时导航容器也要放到放到Scaffold中,也就是说NavHost容器中包含所有的导航页面,需要放在Scaffold函数中,不能放在底部导航的函数中,不然导航栏会出现在屏幕上方,大家可以自己动手去试试。本示例参考了官方文档,大家可以点击这里查看官方文档中的内容。

下面是程序的运行结果,不过图片是静态的,没有导航切换效果。
在这里插入图片描述

4. 内容总结

最后,我们对本章回的内容做一个全面的总结:

  • 底部导航栏的用来和普通导航的用法类似,包含三个步骤;
  • 底部导航栏位于Scaffold中,导航容器也需要放到Scaffold中;
  • 使用Navigation实现底部导航栏比使用Fragment实现导航更加方便一些;

看官们,与Jetpack中底部导航栏相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值