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 即可获取」

相关推荐
scdifsn3 小时前
动手学深度学习12.7. 参数服务器-笔记&练习(PyTorch)
pytorch·笔记·深度学习·分布式计算·数据并行·参数服务器
jackson凌5 小时前
【Java学习笔记】SringBuffer类(重点)
java·笔记·学习
huangyuchi.6 小时前
【Linux】LInux下第一个程序:进度条
linux·运维·服务器·笔记·进度条·c/c++
androidwork6 小时前
Android LinearLayout、FrameLayout、RelativeLayout、ConstraintLayout大混战
android·java·kotlin·androidx
每次的天空6 小时前
Android第十三次面试总结基础
android·面试·职场和发展
wu_android7 小时前
Android 相对布局管理器(RelativeLayout)
android
大写-凌祁7 小时前
论文阅读:HySCDG生成式数据处理流程
论文阅读·人工智能·笔记·python·机器学习
Unpredictable2228 小时前
【VINS-Mono算法深度解析:边缘化策略、初始化与关键技术】
c++·笔记·算法·ubuntu·计算机视觉
傍晚冰川8 小时前
FreeRTOS任务调度过程vTaskStartScheduler()&任务设计和划分
开发语言·笔记·stm32·单片机·嵌入式硬件·学习
李斯维8 小时前
循序渐进 Android Binder(二):传递自定义对象和 AIDL 回调
android·java·android studio