AI智能
改变未来

Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单

Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单 | Stars-One的杂货小窝

Compose给我们提供了一个Material Design样式的首页组件(

Scaffold

),我们可以直接套用从而完成一个APP的首页界面

本系列以往文章请查看此分类链接Jetpack compose学习

由于Scaffold中还包含有其他的组件,所以讲解Scaffold先讲解前置的一些组件

TopAppBar

首先,便是TopAppBar,其本质就是我们Android原生常见的Toolbar,不过其封装的比较好,可以快速构建,下面是其的参数列表

TopAppBar(title: @Composable () -> Unit,modifier: Modifier = Modifier,navigationIcon: @Composable (() -> Unit)? = null,actions: @Composable RowScope.() -> Unit = {},backgroundColor: Color = MaterialTheme.colors.primarySurface,contentColor: Color = contentColorFor(backgroundColor),elevation: Dp = AppBarDefaults.TopAppBarElevation)
  • title

    标题,接收Compose组件,可以传个Text文本进去

  • modifier

    修饰符,详情见上一章节

  • navigationIcon

    导航图标

  • actions

    动作组件

  • backgroundColor

    背景色

  • contentColor

    内容颜色

  • elevation

    阴影

可能说的那么明确,我们直接上代码和效果图,各位就清晰了

TopAppBar(navigationIcon = {IconButton(onClick = {}) {Icon(Icons.Filled.Menu, null)}},title = {Text("stars-one的测试应用")},actions = {IconButton(onClick = {}) {Icon(Icons.Filled.Share, null)}IconButton(onClick = {}) {Icon(Icons.Filled.Settings, null)}})

效果图如下

FloatingActionButton

比较常见的悬浮按钮,一般里面是个简单的按钮,参数与之前的Button一样,详情请参考Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝

FloatingActionButton(onClick: () -> Unit,modifier: Modifier = Modifier,interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),backgroundColor: Color = MaterialTheme.colors.secondary,contentColor: Color = contentColorFor(backgroundColor),elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),content: @Composable () -> Unit)

使用:

FloatingActionButton(onClick = { /*TODO*/ }) {Icon(imageVector = Icons.Default.Add, contentDescription = null)}

PS: 一般这个与

Scaffold

连用,Scaffold里面可控制FloatingActionButton的位置

除此之外,还有个

ExtendedFloatingActionButton

,这种就是可以带图标和文字的,如下图

ExtendedFloatingActionButton(icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },text = { Text("ADD TO BASKET") },onClick = { /*do something*/ })

ExtendedFloatingActionButton

FloatingActionButton

区别是,

ExtendedFloatingActionButton

是以文字为主,图标是可选的,而

FloatingActionButton

只显示图标

BottomAppBar

这个与之前的TopAppBar参数有所不同,从名字看我们知道其实放在底部的一个Toolbar,但是其本身是不带有位置控制,也是得与Scaffold连用,如果单独使用,效果也是会和TopAppBar的一样放在页面的顶头

BottomAppBar(modifier: Modifier = Modifier,backgroundColor: Color = MaterialTheme.colors.primarySurface,contentColor: Color = contentColorFor(backgroundColor),cutoutShape: Shape? = null,elevation: Dp = AppBarDefaults.BottomAppBarElevation,contentPadding: PaddingValues = AppBarDefaults.ContentPadding,content: @Composable RowScope.() -> Unit)

可以把这个布局看作是个Row布局,里面的参数从名字都能看到出来,设置背景色或者设置padding边距的,这里不再赘述

唯一值得注意的是

cutoutShape

属性,如果在

Scaffold

中,有

BottomAppBar

FloatingActionButton

,可以实现下面的效果

BottomNavigation

BottomNavigation

里面会有N个

BottomNavigationItem

,这里就看你自己准备定义多少个菜单项了

BottomNavigation(modifier: Modifier = Modifier,backgroundColor: Color = MaterialTheme.colors.primarySurface,contentColor: Color = contentColorFor(backgroundColor),elevation: Dp = BottomNavigationDefaults.Elevation,content: @Composable RowScope.() -> Unit)

BottomNavigation

提供的一些参数也就是改变颜色或者阴影,重点是在

BottomNavigationItem

BottomNavigationItem(selected: Boolean,onClick: () -> Unit,icon: @Composable () -> Unit,modifier: Modifier = Modifier,enabled: Boolean = true,label: @Composable (() -> Unit)? = null,alwaysShowLabel: Boolean = true,interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },selectedContentColor: Color = LocalContentColor.current,unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium))

BottomNavigationItem

有个

selected

参数,表示是否选中

icon

则是图标的设置,

label

则是文字,这两个都是需要接收一个组件的

  • selectedContentColor

    选中颜色

  • unselectedContentColor

    未选中颜色

下面直接来个例子讲解

var selectIndex by remember {mutableStateOf(0)}val navList = listOf("首页","发现","我的")BottomNavigation() {navList.forEachIndexed { index, str ->BottomNavigationItem(selected = index == selectIndex, onClick = { selectIndex = index },icon = {Icon(imageVector = Icons.Default.Favorite, contentDescription =null )},label = {Text(str)})}}Text(text = "这是${navList[selectIndex]}")

效果如下所示

Scaffold

Scaffold(modifier: Modifier = Modifier,scaffoldState: ScaffoldState = rememberScaffoldState(),topBar: @Composable () -> Unit = {},bottomBar: @Composable () -> Unit = {},snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },floatingActionButton: @Composable () -> Unit = {},floatingActionButtonPosition: FabPosition = FabPosition.End,isFloatingActionButtonDocked: Boolean = false,drawerContent: @Composable (ColumnScope.() -> Unit)? = null,drawerGesturesEnabled: Boolean = true,drawerShape: Shape = MaterialTheme.shapes.large,drawerElevation: Dp = DrawerDefaults.Elevation,drawerBackgroundColor: Color = MaterialTheme.colors.surface,drawerContentColor: Color = contentColorFor(drawerBackgroundColor),drawerScrimColor: Color = DrawerDefaults.scrimColor,backgroundColor: Color = MaterialTheme.colors.background,contentColor: Color = contentColorFor(backgroundColor),content: @Composable (PaddingValues) -> Unit)

属性说明

  • topBar

    顶部的布局

  • bottomBar

    底部的布局

  • floatingActionButton

    悬浮按钮布局

  • floatingActionButtonPosition

    悬浮按钮位置,有

    FabPosition.End

    (默认)和

    FabPosition.Center

    可选

  • isFloatingActionButtonDocked

    与BottomAppBar配合使用,可以实现底部导航条的裁剪效果,效果可以看下图

  • drawerGesturesEnabled

    是否开启侧边抽屉手势(开启后可侧滑弹出抽屉)

  • drawerShape

    抽屉的形状

  • drawerContent

    侧边抽屉内容,是个Column布局,自己可以顺便排列

  • drawerElevation

    侧边抽屉的阴影

  • drawerBackgroundColor

    侧边抽屉的背景色

  • drawerContentColor

    侧边抽屉内容颜色(似乎是覆盖字体颜色而已)

  • drawerScrimColor

    侧边抽屉遮盖最底层的颜色

基本使用

使用5个属性

topBar
bottomBar
floatingActionButton
floatingActionButtonPosition
isFloatingActionButtonDocked

,实现个简单架构效果

Scaffold(topBar = {TopAppBar(navigationIcon = {IconButton(onClick = {}) {Icon(Icons.Filled.Menu, null)}},title = {Text("stars-one的测试应用")},actions = {IconButton(onClick = {}) {Icon(Icons.Filled.Share, null)}IconButton(onClick = {}) {Icon(Icons.Filled.Settings, null)}})},floatingActionButton = {FloatingActionButton(onClick = { /*TODO*/ }) {Icon(imageVector = Icons.Default.Favorite, contentDescription = null)}},bottomBar = {BottomAppBar(cutoutShape = CircleShape) {}},//注意此参数,可以实现图中那种被裁剪的效果,前提是上面的cutoutShape也有设置isFloatingActionButtonDocked = true,floatingActionButtonPosition = FabPosition.End) {//这里是主界面Text("我是要展示的内容")}

效果如下图所示

底部导航条

我们在上面的基础改下即可(主要是bottomAppBar这个参数),代码如下所示

//当前选择的NavItemvar selectIndex by remember { mutableStateOf(0) }val navTextList = listOf("主页", "发现", "我的")//图标val iconList = listOf(Icons.Default.Home,Icons.Default.Favorite,Icons.Default.AccountBox)Scaffold(topBar = {TopAppBar(navigationIcon = {IconButton(onClick = {}) {Icon(Icons.Filled.Menu, null)}},title = {Text("stars-one的测试应用")},actions = {IconButton(onClick = {}) {Icon(Icons.Filled.Share, null)}IconButton(onClick = {}) {Icon(Icons.Filled.Settings, null)}})},floatingActionButton = {FloatingActionButton(onClick = { /*TODO*/ }) {Icon(imageVector = Icons.Default.Add, contentDescription = null)}},bottomBar = {BottomNavigation() {navTextList.forEachIndexed { index, str ->BottomNavigationItem(label = {Text(str)},selected = index==selectIndex , onClick = {selectIndex = index },icon = {Icon(imageVector = iconList[index], contentDescription = null)})}}},//注意此参数,可以实现图中那种被裁剪的效果,前提是上面的cutoutShape也有设置floatingActionButtonPosition = FabPosition.End) {//这里是主界面//根据底部导航选中的下标改变展示的页面when(selectIndex){0 -> Text("这是首页")1 -> Text("这是发现")2 -> Text("这是我的")}}

效果如下图所示

带侧边抽屉

这里需要注意的是,弹出侧边抽屉是个挂起操作(suspend),所以需要使用到Kotlin中的协程,不过不是涉及太深,我们先知道怎么用即可,后面有空我再补充协程的用法

这里主要是测试了带drawer开头的那几个参数,及点击左上角的菜单按钮弹出侧边抽屉功能(即对应的点击事件)

//状态val scaffoldState = rememberScaffoldState()//协程的作用域val scope = rememberCoroutineScope()//当前选择的NavItemvar selectIndex by remember { mutableStateOf(0) }val navTextList = listOf("主页", "发现", "我的")//图标val iconList =listOf(Icons.Default.Home, Icons.Default.Favorite, Icons.Default.AccountBox)Scaffold(scaffoldState = scaffoldState,topBar = {TopAppBar(navigationIcon = {IconButton(onClick = {//使用协程scope.launch {//改变状态,显示drawer抽屉scaffoldState.drawerState.open()}}) {Icon(Icons.Filled.Menu, null)}},title = {Text("stars-one的测试应用")}, actions = {IconButton(onClick = {}) {Icon(Icons.Filled.Share, null)}IconButton(onClick = {}) {Icon(Icons.Filled.Settings, null)}})},floatingActionButton = {FloatingActionButton(onClick = { /*TODO*/ }) {Icon(imageVector = Icons.Default.Add, contentDescription = null)}},bottomBar = {BottomNavigation() {navTextList.forEachIndexed { index, str ->BottomNavigationItem(label = { Text(str) },selected = index == selectIndex,onClick = { selectIndex = index },icon = {Icon(imageVector = iconList[index],contentDescription = null)})}}},//注意此参数,可以实现图中那种被裁剪的效果,前提是上面的cutoutShape也有设置floatingActionButtonPosition = FabPosition.End,drawerContent = {Text("这是抽屉的内容")},drawerContentColor = Color.Black,drawerBackgroundColor = Color.Green,drawerGesturesEnabled = true,drawerScrimColor = Color.Red,drawerShape = RoundedCornerShape(20.dp)) {//这里是主界面//根据底部导航选中的下标改变展示的页面when (selectIndex) {0 -> Text("这是首页")1 -> Text("这是发现")2 -> Text("这是我的")}}

参考

  • Scaffold – Jetpack Compose
  • TopAppBar – Jetpack Compose
  • BottomAppBar官方文档
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单