降Compose十八掌之『飞龙在天』| Layout

公众号「稀有猿诉」        原文链接 降Compose十八掌之『飞龙在天』| Layout

页面布局是GUI应用开发的核心,决定着一个UI具体如何实现。今天将延着路线图来练习『降Compose十八掌』的第二招式,学习一下如何使用Compose中的布局来构建页面。

基础骨架

基础骨架是一个应用页面的最关键结构,可以视为一种基础结构,有了基础结构以后,再补充其他具体的细节就能拼凑出来整体页面。Scaffold就属于这样的一种基础骨架。

Scaffold并不是Compose设计出来的,它是Material Design中的一个基础结构,为复杂的用户界面提供了标准化的平台。它可以把诸如标题栏,内容区域,浮动按扭等不同的UI功能部分组合在一起,形成一个整体连惯的页面。Compose是完全符合Material Design的,因此这里的Scaffold是符合Material Design设计标准的一个实现。

Scaffold主要有四个部分:

  • topBar - 在最顶部的标题栏,可以显示标题,导航按扭,以及菜单。对Android熟悉的同学把它当成ActionBar就可以了。
  • bottomBar - 在最底部的工具栏,一般用来显示页面内部的下一级的Tab导航,或者当成工具栏放一些实用性操作。
  • floatingActionButton - 在右下角悬浮的操作按扭。因为右下角空间有限,所以一般把当前页面最主要的操作放在这里。比如说对于文档类,创建『+』按扭就可以放在这里。
  • content - 内容区域,就是用于显示页面主要内容的地方,无具体形式,需要开发者自己提供其他布局作为内容。唯一需要注意的是,内容Composable lambda有一个参数叫做innerPadding,这个参数的作用是Scaffold对其content区域加的padding,纯大多数情况下,是需要使用此参数的。

Scaffold并不难,很好用,看一个🌰就知道了:

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun ScaffoldExample() {var presses by remember { mutableIntStateOf(0) }Scaffold(topBar = {TopAppBar(colors = mediumTopAppBarColors(containerColor = MaterialTheme.colorScheme.primaryContainer,titleContentColor = MaterialTheme.colorScheme.primary,),title = {Text("降Compose十八掌")})},bottomBar = {BottomAppBar(containerColor = MaterialTheme.colorScheme.primaryContainer,contentColor = MaterialTheme.colorScheme.primary,) {Text(modifier = Modifier.fillMaxWidth(),textAlign = TextAlign.Center,text = "掌式要义",)}},floatingActionButton = {FloatingActionButton(onClick = { presses++ }) {Icon(Icons.Default.Add, contentDescription = "Add")}}) { innerPadding ->Column(modifier = Modifier.padding(innerPadding),verticalArrangement = Arrangement.spacedBy(16.dp),) {Text(modifier = Modifier.padding(8.dp),text ="""“降龙十八掌可说是【武学中的巅峰绝诣】,当真是无坚不摧、无固不破。虽招数有限,但每一招均具绝大威力。北宋年间,丐帮帮主萧峰以此邀斗天下英雄,极少有人能挡得他三招两式,气盖当世,群豪束手。当时共有“降龙廿八掌”,后经萧峰及他义弟虚竹子删繁就简,取精用宏,改为降龙十八掌,掌力更厚。这掌法传到洪七公手上,在华山绝顶与王重阳、黄药师等人论剑时施展出来,王重阳等尽皆称道。”""".trimIndent(),)}}
}

是一个非常标准的Material Design页面。

Scaffold demo

**注意:**如果仔细看Scaffold函数可以发现,前面提到的四大部分,并不是传入数据,而是传入函数。这是声明式代码与传统方式的最大的区别,也是声明式代码的精髓所在,只是声明一个可以用于产生数据的函数作为参数,而非直接把数据当作参数传过去。这样做的好处在于,框架代码可以在真正需要数据的时候通过调用函数来生成数据,避免了数据提前生成。

小结一下,Scaffold是一个非常强大的基础骨架,适用当作页面基础结构来使用,也就是说只能用它来实现一级页面。

布局管理器

有了页面的基础骨架后,就可以往里面填内容了,布局器管理器就是用于组织和管理其他布局和基础部件的约束器,方便对页面元素进行归类和整理。包括三个分类,一是基础布局,是最为基础也最为常用的管理器;二是高级布局,用于一些复杂场景的管理器;三是集合性布局,用于显示数据集合。我们分别来学习。

基础布局

最为基础的布局管理器就三个:Row(行式,水平方向依次排列)Column(列式,垂直方向依次排列)和Box(层叠式,在屏幕上层叠)。用一张图就明了:

Basic layouts

如果有Android基础的同学可以进行类比,Row和Column就相当于LinearLayout,而Box相当于FrameLayout。

高级布局

一般情况下通过基础布局的组合能够实现绝大部分的UI页面,如果遇到更复杂的声明,那就要用更为强大的工具。

约束式布局(ConstraintLayout in Compose)

ConstraintLayout是谷歌推出的一个更为强大的布局,用约束(constraint)统一了概念,可以任意排列子布局。Compose中也是可以使用ConstraintLayout的,并且它可以替代Row,Column和Box。需要注意它并不是Compose的一部分,需要额外添加依赖:

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
@Composable
fun ConstraintLayoutContent() {ConstraintLayout {// Create references for the composables to constrainval (button, text) = createRefs()Button(onClick = { /* Do something */ },// Assign reference "button" to the Button composable// and constrain it to the top of the ConstraintLayoutmodifier = Modifier.constrainAs(button) {top.linkTo(parent.top, margin = 16.dp)}) {Text("Button")}// Assign reference "text" to the Text composable// and constrain it to the bottom of the Button composableText("Text",Modifier.constrainAs(text) {top.linkTo(button.bottom, margin = 16.dp)})}
}

ConstraintLayout demo

ConstraintLayout是非常强大的,可以参考前面的一篇文章来了解它的使用方法,在Compose中使用与在View和XML中使用是一样的。

流式布局(Flow layouts)

流式布局非常强大,也非常常用,它们能够自动折成多行或者多列。Row和Column只能一行或者一列,超出了父布局的宽度和高度后,就看不见了。但FlowRow和FlowColumn则可以自动折叠,变为多行或者多列。并且是智能折叠,不会让子元素只显示一半。这个有非常实用的场景,像显示一些新闻的标签时,就可以用FlowRow。

@Composable
private fun FlowRowSimpleUsageExample() {FlowRow(modifier = Modifier.padding(8.dp)) {ChipItem("Price: High to Low")ChipItem("Avg rating: 4+")ChipItem("Free breakfast")ChipItem("Free cancellation")ChipItem("£50 pn")}
}

FlowRow demo

集合性布局

集合性布局用于显示数据集合,通常都是数量比较多。因为集合数据比较多,远超一个屏幕所能显示得完,因此集合性布局的优势在于用少量的子布局,以复用的方式来把集合数据展示出来。主要有三类水平方向的LazyRow,垂直方向的LazyColumn以及格子式的LazyGrid。使用起来也非常的直观,在其LazyListScope中为子元素生成布局就可以了:

LazyColumn {items(items = messages, // 这是集合key = { message ->// 指定一个用于唯一标记集合中每个元素的idmessage.id}) { message ->// 这里生成集合元素对应的布局MessageRow(message)}
}

需要注意的地方就是有很多个扩展函数items,每个集合性布局都有一个,在import的时候一定要选择与布局对应的那个。另外就是为了能让Compose区别不同的数据元素,一定要给集合元素指定一个可以在此范围内唯一标记元素的id。要不然在编辑的时候可能会有问题。

常见基础部件

最为常用的就是文本(Text),图像(Image)和图标(Icon)了,都不复杂,看个例子就能明白怎么使用。需要说明一下的就是Image是用于显示的图片;而Icon是用于显示小的图标,一般都是矢量图标资源。

@Composable
fun ArtistCard(artist: Artist) {Row(modifier = Modifier.padding(16.dp),verticalAlignment = Alignment.CenterVertically,horizontalArrangement = Arrangement.spacedBy(16.dp)) {Box {Image(painter = painterResource(id = artist.image), contentDescription = "Artist image")Icon(modifier = Modifier.align(Alignment.BottomEnd),imageVector = Icons.Filled.Check, contentDescription = "Check mark",tint = MaterialTheme.colorScheme.surfaceTint)}Column {Text(text = artist.name,style = MaterialTheme.typography.titleMedium,color = MaterialTheme.colorScheme.primary)Text(text = artist.status,style = MaterialTheme.typography.titleSmall,color = MaterialTheme.colorScheme.secondary)}}
}

Widgets

实战练习

今天学习的内容比较多,Compose的布局非常之多,今天的内容只是深入浅出式的学习了一些基础。另外,强烈建议亲手操练一下,推荐官方出品的实战教程Jetpack Compose basics和Basic layouts in Compose。

参考资料

  • Compose layout basics

subscription

欢迎搜索并关注 公众号「稀有猿诉」 获取更多的优质文章!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins教程-15-常用插件-Blue Ocean

上一小节我们学习了Jenkins定时任务构建的方法,本小节我们讲解一下Jenkins常用插件Blue Ocean的使用方法。 Blue Ocean 提供了一套可视化操作界面来帮助创建、编辑 Pipeline 任务。 Blue Ocean 特性: 流水线编辑器:用于创建贯穿始终的持续交…

游戏软件缺少d3dx9_42.dll怎么修复?五种方法助你轻松解决

D3DX9_42.dll的丢失是一种常见的操作系统异常问题,由于日常使用电脑时的不当操作,可能会导致一些dll文件的丢失,D3DX9_42.dll就是其中之一。对于这种情况,我们可以通过谨慎的修复来解决。以下是一种科学的解决D3DX9_42.dll丢失的方…

小白学C++(第一天)基础入门

温馨提醒:本篇文章,请各位c基础不行的童鞋不要贸然观看 C的第一个程序 第一个关键字namespace namespace 是定义空间的名字的关键字,使用格式格式如下: namespace 空间名 { } 其中{ }内的命名空间的成员,可以定义…

初识数组!

目录 1.概念 2.一维数组的创建和初始化 1)数组创建 2)数组的初始化 3)数组的类型 3.一维数组的使用 1) 数组下标 2) 数组元素的打印 3) 数组的输入 4.一维数组在内存中的存储 5.sizeof计算数组元素个数 6.二维数组的创建 1.概念 …

【qt】获取主机信息系统

话不多说,先一睹芳颜! 如果你也想达到这种效果,那咱们就开始吧! 目录 一.登录界面设计1.ui登录设计 二.加载界面1.lineEdit的密码输入模式2.lineEdit按回车跳转的信号3.密码的判断4.创建加载界面5.创建定时器来进行进度条的移动6.定时器执行的槽函数 三.主机信息界面1.主机信息…

解析java128陷阱

一、提要 在java开发时,由于基本类型不能调用方法,在某些方面很不方便,因此产生了包装类。我们把基本类型和对应的包装类的转换叫装箱、拆箱。 1.装箱 基本类型转成包装类对象 关键字valueOf->装箱,可以指定进制: Integer…

非参数检测5——双输入检测系统

在很多情况下,信号常常存在于两个带有独立噪声的信道中。所以很有必要研究双输入系统。双输入系统广泛应用于无线电天文学、水下声波检测和地球物理学等领域。

视频融合共享平台LntonCVS视频监控汇聚平台工业视频监控系统

LntonCVS是一款功能强大、灵活部署的安防视频监控平台,具备广泛的扩展性和视频能力。它支持多种主流标准协议,如国标GB28181、RTSP/Onvif、RTMP,同时还能兼容厂家的私有协议和SDK,如海康Ehome、海大宇等。除了传统的安防监控功能外…

HSG金属表面缺陷检测

HSG金属表面缺陷检测 1. 项目背景1.1 项目简述1.2 项目目标 2. 解决方案3. 数据集3.1 收集各种缺陷的图片3.2 利用有限图片创造更多可能3.3 分割图像3.4 打标签 4. 部分代码4.1 数据集划分4.2图像分割4.3 训练模型4.4 预测 5. 预测结果 1. 项目背景 1.1 项目简述 iPad HSG 的…

Qt json和xml操作

学习目标: 认识json和xml读写操作 前置环境 运行环境:qt creator 4.12 学习内容 XML XML(Extensible Markup Language)是一种标记语言,是一种用于描述数据结构的语言。它非常适合用于存储和传输数据。 XML 的主要特点如下: 可扩展性:XM…

数组算法(二):交替子数组计数

1. 官方描述 给你一个二进制数组nums 。如果一个子数组中 不存在 两个 相邻 元素的值 相同 的情况,我们称这样的子数组为 交替子数组 。 返回数组 nums 中交替子数组的数量。 示例 1: 输入: nums [0,1,1,1] 输出: 5 解释&#…

项目一单机安装基于LNMP结构的WordPress网站 web与数据库服务分离

网站的类型: Jave:LNMT PHP:LNMP Python: LNMU 项目部署: 1.项目的类型(项目的开发语言) 2.项目运营平台的技术选择 3.尽快让项目运行起来 all in one部署 4. 架构的优化 配置ansible管理环境 配置nginx 配置数据库服务…

leetcode:编程基础0到1

文章目录 交替合并字符串str.length();StringBuilder类型 ,toString()append() ,chatAt()题目描述 交替合并字符串 str.length(); 输出字符串str的长度 StringBuilder类型 ,toString() append() ,chatAt() 题目描述 class Solution {public String …

python获取文件列表按照文件修改时间进行排序,默认按照文件名时间戳排序

python获取文件列表按照文件修改时间进行排序,默认按照文件名时间戳排序 1、流程 1、获取文件绝对路径下的所有文件 2、通过os.path.getmtime获取每个文件的修改时间,并与文件组成元组,方便后续排序 3、默认按照时间戳降序,否则按照按修改时间排序文件列表(从最晚到最早)…

开个技术外挂|用技术轻松实现GPU显卡冷却风扇噪声控制

GPU显卡冷却风扇噪声分析 游戏玩家可能有这样的体验:当显卡卖力工作的时候,明显感觉到从机箱传来的噪声变大了。这是因为系统监测到芯片有过热风险,从而自动提升了冷却风扇的转速。 如下图所示,当GPU显卡处于 20C 时,风…

212.贪心算法:跳跃游戏(力扣)

代码解决 class Solution { public:bool canJump(vector<int>& nums) {int cover 0; // 初始化覆盖范围if (nums.size() 1) return true; // 如果数组长度为1&#xff0c;直接返回 true// 遍历数组&#xff0c;直到当前覆盖范围for (int i 0; i < cover; i…

【易捷海购-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【活动行】参与上海两场线下活动,教育生态行业赛总决赛活动和WAIC人工智能大会活动 - 上海活动总结

目录 背景决赛最后一公里领域范围 决赛作品AI智教相机辅导老师Copilot辅导老师Copilot雅思写作竞技场 优秀作品总结 背景 决赛 百度发起的千帆杯教育生态行业赛于2024年7月4日进行线下决赛&#xff0c;博主虽然没能进入决赛&#xff0c;但也非常荣幸能够以嘉宾身份到现场给进…

【VUE基础】VUE3第四节—核心语法之computed、watch、watcheffect

computed 接受一个 getter 函数&#xff0c;返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。 创建一个只读的计算属性 ref&#xff1a; <template><div cl…

<PLC><汇川><串口485>汇川Eazy521系列PLC与特域水冷机进行485通讯的设置

前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如…