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

一、前言

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

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

二、内容

1、PPT介绍scaffold

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就可跳转。

cpp 复制代码
@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 即可获取」

相关推荐
二流小码农1 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少2 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker2 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋2 小时前
Android 协程时代,Handler 应该退休了吗?
android
tingshuo291711 小时前
S001 【模板】从前缀函数到KMP应用 字符串匹配 字符串周期
笔记
火柴就是我16 小时前
让我们实现一个更好看的内部阴影按钮
android·flutter
砖厂小工1 天前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github
张拭心1 天前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
张拭心1 天前
Android 17 来了!新特性介绍与适配建议
android·前端
Kapaseker1 天前
Compose 进阶—巧用 GraphicsLayer
android·kotlin