降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 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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端vue打印后端对象为[object,object]

今天给自己项目进行编写前端页面时,惊讶的发现,自己进行打印后端传递的对象,一直显示未[object,object],如下图所示: 感觉很奇怪,于是我猜测是不是自己获取的返回数据的问题,在进行添加了datat…

Windows10/11家庭版开启Hyper-V虚拟机功能详解

Hyper-V是微软的一款虚拟机软件,可以使我们在一台Windows PC上,在虚拟环境下同时运行多个互相之间完全隔离的操作系统,这就实现了在Windows环境下运行Linux以及其他OS的可能性。和第三方虚拟机软件,如VMware等相比,Hyp…

云计算【第一阶段(28)】DNS域名解析服务

一、DNS解析的定义与作用 1.1、DNS解析的定义 DNS解析(Domain Name System Resolution)是互联网服务中的一个核心环节,它负责将用户容易记住的域名转换成网络设备能够识别和使用的IP地址。一般来讲域名比 IP 地址更加的有含义、也更容易记住…

202487读书笔记|《我有个拥抱,你要不要》——生活从来如此,你的态度赋予它意义

202487读书笔记|《我有个拥抱,你要不要》——生活从来如此,你的态度赋予它意义 《我有个拥抱,你要不要》作者一天到晚气fufu,挺有愛的小漫画,适合用来看图说话锻炼小语言,我看的很快乐也写得很痛快&#xf…

打卡第6天----哈希表

每天进步一点点,滴水石穿,日积月累,不断提升。 数组和链表章节告一段落。开启哈希表相关的。 哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里 一、有效的字母异位词 leetcode题目编号:242 题目描述: 给定两个字符串 s 和 t ,编写一个函数…

国内教育科技公司自研大语言模型

好未来的数学大模型九章大模型(MathGPT) 2023年8月下旬,在好未来20周年直播活动中,好未来公司CTO田密宣布好未来自研的数学领域千亿级大模型MathGPT正式上线并开启公测。根据九章大模型的官网介绍,九章大模型&#xff…

语言模型的进化:从NLP到LLM的跨越之旅

在人工智能的浩瀚宇宙中,自然语言处理(NLP)一直是一个充满挑战和机遇的领域。随着技术的发展,我们见证了从传统规则到统计机器学习,再到深度学习和预训练模型的演进。如今,我们站在了大型语言模型&#xff…

搭建基础库~

前言 项目中会用到工具库、函数库以及一些跟框架绑定的组件,如果这些基础模块每个项目都实现一套,维护起来那真的头大,你说呢😉 搭建流程 准备工作 创建文件夹myLib、安装Git以及pnpm 目录大概就系这样子: myLib ├…

你真的会信息收集嘛,4k字渗透测试信息收集10大技巧

前言 在渗透测试中,信息收集是非常关键的一步,它为后续的漏洞发现和利用提供了重要的基础。以下是非常详细的信息收集方式: 一、被动信息收集 被动信息收集是指在不与目标系统直接交互的情况下,通过公开渠道获取目标系统的相关…

LabVIEW在半导体自动化测试中的应用

半导体制造的复杂性和精密度要求极高,每一个生产步骤都需要严格的控制和监测。自动化测试设备在半导体制造中起到了关键作用,通过精密测量和数据分析,确保产品质量和生产效率。本文介绍如何使用LabVIEW结合研华硬件,开发一个用于半…

Nacos注册中心相关错误记录

文章目录 1,com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:jar:unknown was not found1.1 定位及解决方案1.2,简要说明dependencyManagement的作用 2,nacos启动失败2.1 解决方案 1,com.alibaba.cloud:spring-c…

白嫖A100活动来啦,书生·浦语大模型全链路开源体系

扫码参加即可获得: 第一节 书生浦语大模型全链路开源体系 书生浦语大模型的开源历程。 从模型到应用的典型流程 书生浦语的开源体系,包含从数据、预训练、微调、部署、评测、应用等环节

无线领夹麦克风品牌排名,揭秘国产领夹麦克风哪个品牌好

在自媒体行业迅猛发展的浪潮中,领夹麦克风作为音频采集的关键设备,其市场需求正经历着前所未有的激增。面对市场上众多品牌和型号的选择,如何做出既符合个人需求又不失专业水准的决策,成为了消费者亟待解决的问题。 我特意为大家…

逻辑回归中的损失函数

一、损失函数介绍: 与回归问题成本函数不同的是,逻辑回归模型(解决分类问题)的成本函数在获得损失J的时候不再用真实值y与预测值y^的差值计算损失,真实值y不再出现在公式中作为计算项。 首先,该次训练损失…

Gradle基础:从入门到掌握

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 在现代软件开发中,自动化构建工具是提高效率和管理依赖的重要手段。而Gradle作为一种灵活且强大的构…

中国各省金融监管水平-测算数据(2006-2022年)

金融监管水平是指政府及其指定机构通过法律法规对金融机构及其市场行为进行监督、管理与规范的能力和效率,以维护金融体系稳定、保护投资者和消费者权益、促进公平竞争及支持经济增长。衡量金融监管水平的指标多样,常见的一种计算方式是金融监管支出与金…

linux指令练习

二、touch、vi练习: 1、在root家目录下创建目录A1和B1 2、进入B1下同时创建三个文件m1, m2 , n1,单独创建目录N1 3、进入到A1目录中分别创建一个文件t1,k2,同时创建目录F1,F2 4、删除B1下的所有1结尾的文件或者目录 5、删除A1目录…

容易涨粉的视频素材在哪找啊?爆款涨粉的视频素材网站有这几个

亲爱的读者,大家好!今天我们要探讨一个至关重要的问题:在充满竞争的视觉时代,如何使自己的短视频脱颖而出并吸引更多粉丝?关键在于使用那些既酷炫又高质量的视频素材!下面就向大家推荐几个顶级视频素材网站…

【分布式系统】Filebeat+Kafka+ELK 的服务部署

目录 一.实验准备 二.配置部署 Filebeat 三.配置Logstash 四.验证 一.实验准备 结合之前的博客中的实验 主机名ip地址主要软件es01192.168.80.101ElasticSearches02192.168.80.102ElasticSearches03192.168.80.103ElasticSearch、Kibananginx01192.168.80.104nginx、Logs…

vue对axios进行请求响应封装

一、原因 像是在一些业务逻辑上,比如需要在请求之前展示loading效果,或者在登录的时候判断身份信息(token)等信息有没有过期,再者根据服务器响应回来的code码进行相应的提示信息。等等在请求之前,之后做的一…