欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > Android笔记【12】脚手架Scaffold和导航Navigation

Android笔记【12】脚手架Scaffold和导航Navigation

2024/12/26 18:25:52 来源:https://blog.csdn.net/m0_72696598/article/details/144223095  浏览:    关键词:Android笔记【12】脚手架Scaffold和导航Navigation

 

一、前言

        学习课程时,对于自己不懂的点的记录。

        对于cy老师第二节课总结。

二、内容

1、PPT介绍scaffold

5955d22a9cfb45b8bfcad74a7ecc4817.png

2、开始代码实操

先新建一个screen包,写一个Homescreen函数,包括四个页面。

再新建一个compenent包,写一个displayText函数,是对四个页面容器的统一封装。里面是一个Box容器修饰。再回到Homescreen中传入不同参数以示区别。

在screen包中,创建一个Screen的类来管理这些界面。可继承的,这个类参数不仅要有route,title,icon 还要有一个加载页面函数 @Composable ()->unit 。在这个类里面实现界面的数据对象,最后将这些对象存在screens列表中。

在screen包中,创建一个Mainscreen函数,写脚手架。要传入当前页面可以用currentScreen变量来记录到内存,并注意变量是MutableState<Screen>

好。按照这样写,从topAppBar开始写,最后content大括号部分Box容器可以用currentScreen.value.loadScreen.invoke()展示页面主体及上面效果。

topAppbar部分的action里继续写下拉菜单。先设置一个变量expanded表示下来与否,写一个Button里面是DropDownMenu。这一部分用screens.forEach来设置,并在最后加一个退出图标。最后将这繁琐一大部分放到Compenent包里创建MenuViews。

再写Bottombar导航NavigationBarItem部分,也是screens.forEach 选中页面,点击切换。同样剪切到Compenent的BottomViews里。

然后写悬浮按钮。FloatingActionButton。点击就将currentScreen切换到HomeScreen,这里面还有一些设计样式的布局。

最后写侧拉页面,在component包里新建一个DrawViews函数。drawContent分为DrawerHead和DrawerBottom。DrawerHead细致写:

val (imgRef,titleRef,contentRef) = remember{createRefs()}
createVerticalChain(titleRef,contentRef, chainStyle = ChainStyle.Spread)

没听清这两个约束布局效果。设置水平竖直引导线控制位置。写了三个部分。

DrawerBottom写导航。Screen.forEach后,NavigationBarItem有图标标签,选中就跳转,还可以颜色修饰。主页面的跳转也可以改成

DrawViews(drawerState,currentScreen)

最后将DrawViews和MainScreen结合。记录一个状态变量,但无法直接设置值,需要在协程中打开运行。在DrawViews退出操作也同样是协程。

OK!写完!!后面还有一些对于代码优化方面内容。

优化一:将状态封装定义一个类StateHolder,实现一个rememberState函数。定义一个容器,四个状态就是类里面属性。实现一个组合函数,将状态默认值保存至内存中,需要时再提取出来,再用这四个值创建四个对象。

//    val currentScreen:MutableState<Screen> =remember{ mutableStateOf(Screen.HomePage) }
//    val expanded = remember { mutableStateOf(false) }
//    val drawerState = rememberDrawerState(DrawerValue.Closed)
//    val scope= rememberCoroutineScope()val stateHolder= rememberState()

改成 

//将状态保存在状态容器中
class stateHolder(val drawerState: DrawerState,val currentScreen: MutableState<Screen>,val expanded:MutableState<Boolean>,val scope: CoroutineScope) {}@Composable
fun rememberState(drawerState: DrawerState= rememberDrawerState(initialValue = DrawerValue.Closed),currentScreen: MutableState<Screen> = remember { mutableStateOf(Screen.HomePage) },expanded:MutableState<Boolean> = remember { mutableStateOf(false) },scope: CoroutineScope= rememberCoroutineScope()):stateHolder
= remember(drawerState,currentScreen,expanded,scope) {  //stateHolder(drawerState,currentScreen,expanded,scope)
}

优化二:利用导航。(自己先同步和定义和库依赖)

 定义MainScreen2。不需要界面,只需要route,icon,title。加载页面也是我们自己操作。定义导航图,导航数组,控件(数组的)。传递参数route。继续写NavigationBarItem一样的选中调换。区别:不用记录当前状态,只需route就可跳转。

@Composable
fun NavigationGraphScreen(navController: NavHostController){//顶层的导航控件一定要是数组的 否则后面会出错NavHost(navController = navController, startDestination = "home") {composable(route = "home") {HomeScreen()}composable(route = "config") {ConfigScreen()}composable(route = "help") {HelpScreen()}}
}@Preview
@Composable
fun MainScreen2() {val navController: NavHostController = rememberNavController()Scaffold(bottomBar = {BottomAppBar {screens.forEach{NavigationBarItem(selected =navController.currentDestination?.route==it.route ,onClick = {navController.navigate(it.route)},icon = {Icon(it.icon, contentDescription = "null")})}}}) {Box (modifier = Modifier.padding(it)){NavigationGraphScreen(navController)}

细节:将页面压栈 的清栈操作需要考虑。

现在放上源代码:

【超级会员V1】通过百度网盘分享的文件:navigati…
链接:https://pan.baidu.com/s/1xetKh4LJ9SMQRA2gMUi43g?pwd=rx2c 
提取码:rx2c
复制这段内容打开「百度网盘APP 即可获取」

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com