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

相关推荐
MarisolHu1 小时前
前端学习笔记-Vue篇-02
前端·vue.js·笔记·学习
画个太阳作晴天1 小时前
Android10 设备死机的问题分析和解决
android·framework·anr
先知demons2 小时前
uniapp开发微信小程序笔记10-触底加载
前端·笔记·微信小程序·小程序·uni-app
B1nna3 小时前
外卖开发(三)开发笔记——AOP实现实现公共字段填充、主键回显、抛异常和事务管理
笔记
我的老子姓彭3 小时前
C++学习笔记
c++·笔记·学习
SHUIPING_YANG4 小时前
Typora设置自动上传图片到图床
android
Ai 编码助手4 小时前
php多进程那点事,用 swoole 如何去解决呢
android·php·swoole
m0_689618284 小时前
亚毫米级纤维机器人,如何在腔内“大显身手”
网络·笔记·机器人
炸毛的飞鼠4 小时前
PWN的简单了解
笔记·学习
ydl11284 小时前
机器学习周志华学习笔记-第13章<半监督学习>
笔记·学习·机器学习