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*/ }
)

ExtendedFloatingActionButtonFloatingActionButton区别是,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中,有BottomAppBarFloatingActionButton,可以实现下面的效果

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这个参数),代码如下所示

//当前选择的NavItem
var 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()
//当前选择的NavItem
var 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("这是我的")
} }

参考

Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单的更多相关文章

  1. Jetpack Compose学习(5)——从登录页美化开始学习布局组件使用

    原文:Jetpack Compose学习(5)--从登录页美化开始学习布局组件使用 | Stars-One的杂货小窝 本篇主要讲解常用的布局,会与原生Android的布局控件进行对比说明,请确保了解A ...

  2. Jetpack Compose学习(2)——文本(Text)的使用

    原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ...

  3. Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用

    原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ...

  4. Jetpack Compose学习(8)——State及remeber

    原文地址: Jetpack Compose学习(8)--State状态及remeber关键字 - Stars-One的杂货小窝 之前我们使用TextField,使用到了两个关键字remember和mu ...

  5. Jetpack Compose学习(1)——从登录页开始入门

    原文地址:Jetpack Compose学习(1)--从登录页开始入门 | Stars-One的杂货小窝 Jetpack Compose UI在前几天出了1.0正式版,之前一直还在观望,终于是出了正式 ...

  6. Jetpack Compose学习(6)——关于Modifier的妙用

    原文: Jetpack Compose学习(6)--关于Modifier的妙用 | Stars-One的杂货小窝 之前学习记录中也是陆陆续续地将常用的Modifier的方法穿插进去了,本期就来详细的讲 ...

  7. Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)

    原文:Jetpack Compose学习(9)--Compose中的列表控件(LazyRow和LazyColumn) - Stars-One的杂货小窝 经过前面的学习,大致上已掌握了compose的基 ...

  8. Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用

    原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ...

  9. amazeui学习笔记--css(常用组件10)--导航条Topbar

    amazeui学习笔记--css(常用组件10)--导航条Topbar 一.总结 1. 导航条:就是页面最顶端的导航条:在容器上添加 .am-topbar class,然后按照示例组织所需内容.< ...

随机推荐

  1. 十六:使用JDBC对数据库进行CRUD

    一.statement对象介绍 Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可. Statement对象的exe ...

  2. 09.SpringMVC之类型转换

    一. 类型转换器 前端传入的值,从表单中传入的值,都是字符串或者是字符串数组的形式传入的,在后端需要进行手动的转换类型,然后才能正确的使用. 框架一般对常见的数据类型的转换进行了封装提供,如字符串转换 ...

  3. CentOS 6.x 系统中安装原生 Hadoop 2

    2020年整理博客发现原文地址已经失效,推荐学习地址厦门大学数据库实验室 本教程适合于在 CentOS 6.x 系统中安装原生 Hadoop 2,适用于Hadoop 2.7.1, Hadoop 2.6 ...

  4. cmd进入pycharm所创建的虚拟环境

    进入cmd命令,进入虚拟环境所在文件夹.(pycharm每创建一个新项目就会创建一个虚拟环境,位于项目下venv下Script) E:\virtualenv\crawl1\Scripts>act ...

  5. Ant的使用(一)

    <?xml version="1.0" encoding="UTF-8"?> <project name="projectName& ...

  6. 获取本地请求的真实IP地址

    1 /** 2 * 自定义访问对象工具类 3 * 4 * 获取对象的IP地址等信息 5 * 6 */ 7 public class CusAccessObjectUtil { 8 9 /** 10 * ...

  7. 整理之BroadcaseReceiver

    广播的分类 有序广播:按接收器优先级从高到低接受消息,一次只能有一个接收器处理消息.中途可以被截断. 无序广播:所有接收器同时接受消息并处理,无法拦截. 本地广播:只能在本应用内传播的无需广播.上面两 ...

  8. 字符串截取子串(Java substring , indexOf)

    前言 因为之前java课设做的是股票分析系统,我找的接口返回的是一个.csv文件,因为这种文件里面的数据是以逗号分隔的,所以要对数据进行分析的时候需要截取子串,并且以逗号作为截取的标志.所以接下来就说 ...

  9. 【第十四篇】- Maven 自动化构建之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven 自动化构建 自动化构建定义了这样一种场景: 在一个项目成功构建完成后,其相关的依赖工程即开始构建,这样可以保证其依赖项目的稳定. 比如一个团队正在开发一个项目 bus-core-api, ...

  10. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...