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

news2024/9/20 8:12:44

公众号「稀有猿诉」        原文链接 降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 constrain
        val (button, text) = createRefs()

        Button(
            onClick = { /* Do something */ },
            // Assign reference "button" to the Button composable
            // and constrain it to the top of the ConstraintLayout
            modifier = 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 composable
        Text(
            "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 ->
            // 指定一个用于唯一标记集合中每个元素的id
            message.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.coloradmin.cn/o/1907667.html

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

相关文章

成长过程,摔倒不要紧,爬起来、改过、前进

无论何时何地,我们都有重头再来的能力,这份生生不息的力量来自天之灵根; 学习过程会有跌倒,这是很正常的节奏次序,不能掩盖自己的过失、自欺欺人,这不是过失,摔倒了就拍拍身上的灰尘&#xff…

3 个令人惊艳的 AI 开源工具,诞生了!

大家好,今天继续聊聊 AI 科技圈发生的那些事。分享几个最新好玩、实用的AI工具。更多最新技术,文末加入我们。 LivePortrait LivePortrait:一款可以轻松让一幅肖像栩栩如生的工具 它可以精准操控眼睛和嘴唇动作: 让静态照片变为…

关于在自行封装的组件库中(使用vue-class-component)使用Vue-i18n无法正常翻译的解决办法

文章目录 介绍背景现象1解决办法 现象2原因分析解决办法 最终方案 介绍 大家或多或少都用过别人封装的组件库,甚至有人或者公司内有自行封装的一些公用组件库,而国际化翻译现在已经是各大项目中必不可少的一个插件了,但组件库中使用 i18n 进…

AI视频创作一条龙!达摩院“寻光”平台炸场WAIC,突破可控编辑难题

卡奥斯智能交互引擎是卡奥斯基于海尔近40年工业生产经验积累和卡奥斯7年工业互联网平台建设的最佳实践,基于大语言模型和RAG技术,集合海量工业领域生态资源方优质产品和知识服务,旨在通过智能搜索、连续交互,实时生成个性化的内容…

基于Java+SpringMvc+Vue技术的实验室管理系统设计与实现(6000字以上论文参考)

博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c等开发语言,以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架…

正态、威布尔、指数分布、伽马分布、对数正态分布介绍

目录 正态、威布尔、指数分布、3.1 概念介绍概率密度函数(PDF)累积分布函数(CDF)性质应用 3.2 参数及绘图参数概率密度函数(PDF)累积分布函数(CDF)绘图图像解读 3.3 指数分布拟合代码…

Java面经知识点汇总版

Java面经知识点汇总版 算法 14. 最长公共前缀(写出来即可) Java 计算机基础 数据库 基础 SQL SELECT first_name, last_name, salary FROM employees WHERE department Sales AND salary > (SELECT AVG(salary)FROM employeesWHERE department Sal…

阶段三:项目开发---大数据开发运行环境搭建:任务6:安装配置HBase

任务描述 知识点:安装配置HBase 重 点: 安装配置HBase 难 点:无 内 容: 本阶段任务是安装配置HBase,实时飞行数据是保存在HBase中的,因为HBase具有高效的读写能力,在当前项目中我们是…

网络资源模板--Android Studio 外卖点餐App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 原创外卖点餐:基于Android studio 实现外卖(点)订餐系统 非原创奶茶点餐:网络资源模板--基于 Android Studio 实现的奶茶点餐App报告 一、项目演示 网络资源模板--基于Android …

通义千问Qwen-VL-Chat大模型本地部署(一)

目录 前言 环境准备 软件安装 其它库安装启动项目 FASTAPI 小结 前言 人工智能大模型是一种能够利用大数据和神经网络来模拟人类思维和创造力的人工智能算法。它利用海量的数据和深度学习技术来理解、生成和预测新内容,通常情况下有数十亿乃至数百亿个参数&#xf…

关于Web开发的详细介绍

目录 一、什么是Web? 二、Web网站的工作流程和开发模式 (1)简单介绍 (2)工作流程 1、第一步 2、第二步 (3)Web网站的开发模式 1、前后端分离开发模式 ​编辑2、混合开发模式 三、开发W…

36.哀家要长脑子了!--前缀和差分

前缀和 1.一维的795. 前缀和 - AcWing题库 前缀和公式 s[i] a[1] a[2] a[3] ... a[i] 即 s[i] s[i-1] a[i] #include<iostream> using namespace std;const int N 1e5 10; int a[N], s[N];int main(){int m, n;cin >> n >> m;for(int i 1; i <…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【加解密(ArkTS)】

加解密(ArkTS) 以AES 128密钥为例&#xff0c;完成加解密。具体的场景介绍及支持的算法规格。 开发步骤 生成密钥 指定密钥别名。初始化密钥属性集。调用[generateKeyItem]生成密钥&#xff0c;具体请参考[密钥生成]。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/l…

数据库之MQL

1&#xff0c;查询所有 mysql> select * from grade;2&#xff0c; mysql> select id,firstname,lastname from grade;3&#xff0c; mysql> select firstname,lastname from grade where id > 4;4&#xff0c; mysql> select * from grade where sex f;5&…

pandas数据分析(8)

描述性统计量和数据聚合 描述性统计量 描述性统计量通过量化数据来概括数据集。DataFrame和Series可以通过sum、mean、count等方法来获取各种描述性统计量。在默认情况下会按照axis0返回一个Series&#xff0c;也就是说会得到一个有关列的统计量&#xff1a; 如果要计算行的统…

【解决Windows11系统Windows Hello不能使用的问题】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Windows Hello是什么&#xff1f;二、使用步骤1.购买一个摄像头2.开始配置 三、异常解决1.内置管理员不能使用2.没找到合适的摄像头3.摄像头需要专用驱动4.…

CSS技巧 - 一日一例 (1):会讨好的热情按钮

题外话: 从今天开始,我准备开设一个新的专栏,专门写 使用CSS实现各种酷炫按钮的方法,本专栏目前准备写40篇左右,大概会完成如下按钮效果: 今天,我来介绍第一个按钮的实现方法:会讨好的热情按钮。为什么我给它起这样的名字呢?你看它像不像一个不停摇尾巴的小黄?当你鼠…

Java---包装类与泛型

1.包装类 1.1 包装类 在Java中&#xff0c;由于基本数据类型不是继承Object类&#xff0c;为了在泛型代码中可以支持基本数据类型&#xff0c;Java给每个基本数据类型各自提供了一个包装类。 如下图 除了char和int基本数据类型的包装类型有点特别&#xff0c;其他的都是首字…

百川工作手机实现销售管理微信监控系统

在瞬息万变的商业战场中&#xff0c;每一分效率的提升都是企业制胜的关键。传统销售管理模式已难以满足现代企业对精准、高效、合规的迫切需求。今天&#xff0c;让我们一同探索如何利用工作手机这一创新工具&#xff0c;为您的销售团队装上智能翅膀&#xff0c;开启销售管理的…

ELfK logstash filter模块常用的插件 和ELFK部署

ELK之filter模块常用插件 logstash filter模块常用的插件&#xff1a; filter&#xff1a;表示数据处理层&#xff0c;包括对数据进行格式化处理、数据类型转换、数据过滤等&#xff0c;支持正则表达式 grok 对若干个大文本字段进行再分割成一些小字段 (?<字段名…