原文:Jetpack Compose学习(11)——Navigation页面导航的使用 - Stars-One的杂货小窝
在Android原生的View开发中的,也是有Navigation
,原生我之后可能再出篇教程,今天讲解的则是compose版本的Navigation组件的使用
本系列以往文章请查看此分类链接Jetpack compose学习
说明
在原生中,官方比较推荐使用单Activity+多Fragment模式来构建一个APP,而Fragment的切换需要使用FragmentManager来进行管理,比如add replace等方法,对于开发者来说,也是比较繁琐,于是官方在Jetpack组件中就是推出了Navigation的库,可以方便开发者快速去管理多Fragment的页面堆栈问题
而今天的主要针对compose,compose的架构也是一个Activity+多个可组合项,而如何去切换可组合项?
以往的做法就是定义一个选中下标,下标更改了,重新渲染一下页面,从而达到切换页面的效果
而有了Navigation,则是可以在使用层面更为优雅和规范,也是方便管理,不易出现奇奇怪怪的堆栈问题等
基本使用
这里我们以一个使用了NavigationBar
组件的页面进行改造
PS:这里我是新版本的AS创建的项目,默认使用的是Material3的依赖包,所以底部导航栏组件就是
NavigationBar
,如果是Material2
的依赖包,则是叫BottomNavigation
效果如下图所示:
就是实现了两个底部菜单,然后可以进行页面的切换,代码如下所示:
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Composable
fun MyApp() {
var currentSelect by remember {
mutableStateOf(0)
}
val menuData = listOf(
BottomItemData("首页", Icons.Filled.Home),
BottomItemData("设置", Icons.Filled.Settings)
)
Scaffold(modifier = Modifier.fillMaxSize()
, bottomBar = {
NavigationBar() {
menuData.forEachIndexed { index, bottomItemData ->
NavigationBarItem(
selected = index == currentSelect,
onClick = {
currentSelect = index
},
icon = {
Icon(
imageVector = bottomItemData.icon,
contentDescription = "点击按钮"
)
},
label = {
Text(
text = (bottomItemData.label)
)
},
)
}
}
}
) { innerPadding ->
//下面第3步就是对此部分代码进行更改
//IDE强制要使用者innerPadding,这里就简单的打印一下
println(innerPadding)
if (currentSelect == 0) {
Text("首页")
}else{
Text("设置")
}
}
}
从上面代码中,我们可以看到我们是通过currentSelect
这个变量来进行页面的显示管理,实际上这里管理会比较繁琐,这个时候就得用到今天的主角Navigation
了
1.引入依赖
implementation "androidx.navigation:navigation-compose:2.5.3"
2.声明NavController
首先,就是使用rememberNavController
获得NavController对象
//导航
val navController = rememberNavController()
PS: 之后的跳转和返回上一级就是使用此对象过来就行
3.使用NavHost,声明页面路由
在布局content参数的函数里使用下面这段代码:
NavHost(navController = navController, startDestination = "MainPage") {
//声明名为MainPage的页面路由
composable("MainPage"){
//页面路由对应的页面组件
MainPage()
}
composable("SettingPage"){
SettingPage()
}
}
上面是声明了两个页面,MainPage和SettingPage则是它两的路由名,后面页面跳转需要使用到
NavHost方法中,参数需要上一步的NavController对象,startDestination则是开始的页面为MainPage
简单的解释,就是可以把NavHost也看出一个页面组件,这个组件默认显示的是MainPage页面
源码如下,点击展开
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Composable
fun MyApp() {
var currentSelect by remember {
mutableStateOf(0)
}
//导航
val navController = rememberNavController()
val menuData = listOf(
BottomItemData("首页", Icons.Filled.Home),
BottomItemData("设置", Icons.Filled.Settings)
)
Scaffold(modifier = Modifier.fillMaxSize()
, bottomBar = {
NavigationBar() {
menuData.forEachIndexed { index, bottomItemData ->
NavigationBarItem(
selected = index == currentSelect,
onClick = {
currentSelect = index
},
icon = {
Icon(
imageVector = bottomItemData.icon,
contentDescription = "点击按钮"
)
},
label = {
Text(
text = (bottomItemData.label)
)
},
)
}
}
}
) { innerPadding ->
//IDE强制要使用者innerPadding,这里就简单的打印一下
println(innerPadding)
NavHost(navController = navController, startD