Jetpack Compose之线性布局和帧布局

news2024/11/15 15:36:13

概述

Compose 中的线性布局对应的是Android传统视图中的LinearLayout,不一样的地方是,Compose根据Orientation的不同又将布局分为Column和Row, Column对应传统视图LinearLayout中orientation = “vertical”的情况,Row对应传统视图LinearLayout中orientation = “horizontal”的情况.由于两者内部元素在父容器中的布局和对其方式不同,分成两个组件有助于提供类型安全的Modifier修饰符。而Compose中的帧布局对应的是Android传统View中的FrameLayout,它可以让自己的子组件依次按照顺序推叠。

实例解析

1.线性布局

在Compose中,线性布局根据使用场景的不同,分为Column和Row,Column 是垂直线性布局组件,Row是水平线性布局组件

1.1 Column组件

@Composable
inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
)

上面是Column的参数列表,其中verticalArrangement和horizontalAlignment参数分别可以帮助我们安排子项的垂直/水平位置,在默认情况下,子项会以垂直方向靠上(Arrangment.Top)、水平方向靠左来布置子项的摆放

我们可以以一个例子看下Column的使用

@Composable
fun LinearLayoutDemo() {
    Column(
        modifier = Modifier
            .border(1.dp, color = Color.Red)
            .size(150.dp),
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "Hello World",
            style = MaterialTheme.typography.h6,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
        Text(
            text = "JetPack",
            style = MaterialTheme.typography.h6,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
        Text(
            text = "zhongxj",
            style = MaterialTheme.typography.h6,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
    }
}

运行结果:
在这里插入图片描述

在上面的代码中,我们通过verticalArrangement参数,将Column中的Text摆放到了组件的中间,然后使用Modifier.align修饰符来独立设置子项的对齐规则
这里可能有人会问,不是有horizontalAlignment参数吗,水平方向为啥还要用Modifier.align呢?因为对于垂直布局中的子项,Modifier.align只能设置自己在水平方向的位置,反之水平布局的子项,只能设置自己在垂直方向的位置,就比如我们正在介绍的Column组件,当Column组件中有多个子项时,他们在垂直方向永远是线性排列的,如果允许子项被单独设置,就会出现不好的情况,比如Column中有A,B,C三项,如果配置A的对齐方向是Aligment.Bottom,B为Aligment.Top,这显然是无法实现的,所以Column的子项在垂直方向布局只能通过verticalArragnment进行整体设置。(注意:这里不是说Column只能使用verticalArragnment参数)

注意:在不给Column指定高度、宽度、大小的情况下,Column组件会默认包裹里面的子项,在这个时候我们是无法使用Column参数中的verticalArrangement或者horizontalAlignment来定位子项在Column中的整体位置的

1.2 Row组件

Row组件可以将内部子项按照从左到右的方向水平排列,和Cloumn组件配合使用就可以构建出很丰富美观的界面。下面是一个使用Row组件和Column组件制作的文章卡片,代码如下:

@Composable
fun ArticleCard() {
    Surface(
        shape = RoundedCornerShape(8.dp),
        modifier = Modifier
            .padding(horizontal = 12.dp)
            .fillMaxWidth(),
        elevation = 10.dp,
    ) {
        Surface(modifier = Modifier.padding(12.dp), color = Color(0xeeeeeeee)) {
            Column(modifier = Modifier.padding(12.dp)) {
                Text(
                    text = "JetPack Compose",
                    style = MaterialTheme.typography.h6
                )

                Spacer(modifier = Modifier.padding(vertical = 5.dp))
                Text(
                    text = " Jetpack Compose是第一个使用Kotlin正在开发中的大型项目," +
                            "因此Android团队正在探索Kotlin API指南的新世界,以创建一组特定于Compose API的指南," +
                            "该工作仍在进行中,仍然有很长的路要"
                )

                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    IconButton(onClick = { /*TODO*/ }) {
                        Icon(
                            imageVector = Icons.Filled.Favorite,
                            contentDescription = null, modifier = Modifier.size(16.dp)
                        )
                    }

                    IconButton(onClick = { /*TODO*/ }) {
                        Icon(
                            painterResource(id = R.drawable.comment),
                            contentDescription = null, modifier = Modifier.size(16.dp)
                        )
                    }

                    IconButton(onClick = { /*TODO*/ }) {
                        Icon(
                            painterResource(id = R.drawable.share),
                            contentDescription = null, modifier = Modifier.size(16.dp)
                        )
                    }
                }
            }
        }
    }
}

运行结果:
在这里插入图片描述

从上面的代码中可知,Row的horizontalArrangement参数帮助我们合理配置了按钮的水平位置。可以看到,图标部分,喜欢和分享按钮呈左右两端对齐,Arrangement定义了很多子项对齐的方式,除了Center(居中),Start(水平靠左),End(水平靠右)等常见的对齐方式,还有一些特定场景下的对齐方式,如Space Between,Space Evenly等。

2.帧布局

2.1 Box组件

Box组件是一个能够将里面的子项依次按照顺序堆叠的布局组件,在使用上类似于传统布局的FrameLayout,这个很简单,我们看下一段代码了解下它的使用。

@Composable
fun BoxDemo(){
    Box(modifier = Modifier
        .size(150.dp)
        .background(Color.Green))
    Box(modifier = Modifier
        .size(80.dp)
        .background(Color.Red))

    Text(text = "Hello World")
}

运行结果:
在这里插入图片描述

2.2 Surface组件

Surface从字面上理解是一个平面,在Material Design设计准则中也同样如此,我们可以将很多的组件摆放在这个平台之上,可以设置这个平面的边框,圆角,颜色等.例如,使用Surface实现一个卡片效果,代码如下:

@Composable
fun SurfaceDemo() {
    Surface(
        shape = RoundedCornerShape(8.dp),
        elevation = 10.dp,
        modifier = Modifier
            .width(300.dp)
            .height(100.dp),
        color = Color.Gray
    ) {
        Row(modifier = Modifier.clickable {}) {
            Image(
                painter = painterResource(id = R.drawable.portrait),
                contentDescription = null,
                modifier = Modifier.size(100.dp),
                contentScale = ContentScale.Crop
            )

            Spacer(modifier = Modifier.padding(horizontal = 12.dp))
            Column(
                modifier = Modifier.fillMaxHeight(),
                verticalArrangement = Arrangement.Center
            ) {
                Text(text = "zhongxj", style = MaterialTheme.typography.h6)
                Spacer(modifier = Modifier.padding(vertical = 8.dp))
                Text(text = "海塔灯")
            }
        }
    }
}

运行结果:
在这里插入图片描述

从上面的代码中我们可以看到,在Surface中我们主要编写UI代码,而Surface主要负责整个组件的形状,阴影,背景等,Surface可以帮助我们解耦一些代码,而不必在单个组件上添加很多的Modifier修饰符方法。

很多读者可能会有疑问有了Box为啥还要加一个Surface组件,其实Box和Surface组件还是有区别的,如果我们需要快速设置界面的形状,阴影,边框,颜色等,我们使用Surface会更好,因为这样可以减少Modifier的使用量。而如果我们只是需要简单设置界面背景颜色,大小,且需要简单布局下子项的位置,则可以使用Box

3.Spacer留白

在很多时候,我们需要让组件之间留有空白的间隙,这时候就可以使用Compose提供的Spacer组件,简单用一个demo展示Spacer的使用。

@Composable
fun SpacerDemo(){
   Row {
       Box(modifier = Modifier
           .size(100.dp)
           .background(Color.Green))
       Spacer(modifier = Modifier.width(20.dp))
       Box(modifier = Modifier
           .size(100.dp)
           .background(Color.Yellow))
       Spacer(modifier = Modifier.weight(1f))
       Box(modifier = Modifier
           .size(100.dp)
           .background(Color.Magenta))
   }
}

运行结果
在这里插入图片描述

从上面的代码中可以看出Spacer的另一种使用场景,那就是在代码中使用Box绘制占位的矩形块在没有内容的时候完成可以使用Spacer来替代。

总结

本文主要讲了线性布局和帧布局在Compose中如何使用,其实非常简单,就需要我们多加练习,没有啥技巧。等啥时候我们写Compose的UI和写XML的UI一样熟练的时候,我们的工作效率就会大大的提升,可以用更少的代码实现更炫的UI效果,而且Kotlin和Java还可以混合使用,现在我已经在用Compose写测试的界面了,非常方便,推荐读者也动起来,使用Java的小伙伴可以使用Compose写界面,Java写功能,而使用Kotlin的小伙伴,则可以更方便的使用Compose,一种语言,完成界面和功能,真的特别酷。

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

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

相关文章

Redis入门学习笔记【二】Redis缓存

目录 一、Redis缓存 二、Redis使用缓存遇到的问题 2.1 数据一致性 2.2缓存雪崩 2.3 缓存穿透 2.4 缓存击穿 一、Redis缓存 数据缓存是Redis最重要的一个场景,为缓存而生,在springboot中,一般有两种使用方式: 直接通过RedisT…

helm部署相关服务过程中问题记录

在学习helm部署相关服务过程中出现一些相关问题,自己记录并供大家一起学习!!! 【问题1】部署helm 获取软件包失败 在通过wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz文件过程发现无法…

消息中间件的定义

中间件(middleware)是基础软件的一大类,属于可复用的软件范畴。中间件在操作系统软件,网络和数据库之上,应用软件之下,总的作用是为处于自己上层的应用软件提供运行于开发的环境,帮助用户灵活、高效的开发和集成复杂的…

【软考数据库】第二章 程序语言基础知识

目录 2.1 程序设计语言的基本概念2.2 程序设计语言的基本成分2.3 编译程序基本原理 前言: 笔记来自《文老师软考数据库》教材精讲,精讲视频在b站,某宝都可以找到,个人感觉通俗易懂。 2.1 程序设计语言的基本概念 程序设计语言是…

Nginx中的location规则与rewrite重写

location与rewrite的区别 rewrite :对访问的域名或者域名内的URL路径地址重写 location:对访问的路径做访问控制或者代理转发 从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获…

常见的3d bounding box标注工具

0. 简介 对于3d bounding box而言,近几年随着自动驾驶的火热,其标注工具也日渐多了起来,本篇文章不讲具体的算法,这里主要聚焦于这些开源的3d bounding box标注工具,以及他们是怎么使用的。这里借鉴了我想静静&#x…

牛客前端编程语言错题2

【语法】 名为“ctx”的变量是某个HTML5画布对象的上下文。以下代码绘制的是什么() Ctx.arc(x,y,r,0,Math.PI,true); 在给定点绘制一个矩形 从一个点到另一个点绘制一条直线 在给定点绘制一个半圆 在给定点绘制一个圆 链接:https://www.now…

分布式系统反向代理设计与正向代理

反向代理与正向代理分析 代理服务器:位于发起请求的客户端与原始服务器端之间的一台跳板服务器,代理服务器分为正向代理服务器和反向代理服务器 正向代理 :代理客户端,隐藏了真实的请求客户端,服务端不知道真实的客户…

安全响应中心 — 垃圾邮件事件报告(4.18)

天空卫士安全响应中心邮件安全小组是成都研发中心的核心部门之一。在日常工作中,对大量样本进行分析并提取规则,实现对包含垃圾内容、钓鱼内容的邮件进行检测和隔离,从而抵御对业务电子邮件的入侵,防止钓鱼邮件等隐蔽邮件威胁。其…

9. 树的进阶

9. 树的进阶 ​ 之前我们学习过二叉查找树,发现它的查询效率比单纯的链表和数组的查询效率要高很多,大部分情况下,确实是这样的,但不幸的是,在最坏情况下,二叉查找树的性能还是很糟糕。 例如我们依次往二叉…

基于tensorflow2.x的多GPU并行训练

由于最近训练transformer,在单卡上显存不够,另外一块卡上也无法加载,故尝试使用双卡并行的策略。将基本的流程、遇见的难题汇总在这里。分布策略解释 使用官方给出的tf.distribute.MirroredStrategy作为分布策略。这个策略通过如下的方式运行…

Echarts渲染行政区划,实现聚焦高亮交互

首先需要准备行政区划的JSON数据&#xff0c;可以在DataV获取省市区的JSON数据。 最终效果图 渲染地图 建立一个地图容器&#xff0c;注意要给宽高 <!-- 地图容器 --> <div id"map"></div>请求JSON数据&#xff0c;渲染地图 $(function() {var …

Ubuntu 20版本将动态ip修改为静态ip时,ping 不通网络

问题描述&#xff1a; 在对Ubuntu 20版本将动态ip修改为静态ip时&#xff0c;ping www.baidu.com ping不通了 火狐浏览器没有了网路&#xff0c;下载不了东西 一直卡在这里不动 问题出在哪里还是配置ip dns 网关的问题 如果我们在当初安装ubuntu 时&#xff0c;将网络设置成…

24年专转本想要成功我们一个怎样做

23年转本报名人数创造高峰&#xff0c; 24年转本的同学们 如何脱颖而出&#xff0c;成功转本呢&#xff1f;一、明确转本目的 转本是一场重要的考试&#xff0c;有人把转本比喻为第二次高考。面对这唯一的进入本科院校学习的机会&#xff0c;考还是不考&#xff1f; 很多同…

小六壬学习笔记

小六壬学习笔记 简介前置知识:十二地支和十二时辰适用范围起课&#xff1a;月令日时卦象 疑问&#xff1a;遇到闰月怎么办&#xff1f;禁忌数字起课法手机计算器取余数 简单解卦 简介 马前课&#xff0c;又名&#xff1a;小六壬。 小六壬历史渊源&#xff1a;https://m.sohu.c…

RXJava2的基本概念与常见操作符使用实例解析

RXJava2是什么&#xff1f;可以简单介绍一下其特点和应用场景吗&#xff1f; RXJava2是基于观察者模式和链式编程思想的异步编程库&#xff0c;它可以用来优雅地处理异步操作&#xff0c;比如网络请求、数据库查询、文件I/O等操作&#xff0c;减少了回调嵌套&#xff0c;提高了…

【LeetCode】剑指 Offer 68. 二叉树中两个节点的最低公共祖先 p326 -- Java Version

1. 题目介绍&#xff08;68. 二叉树中两个节点的最低公共祖先&#xff09; 面试题68&#xff1a;二叉树中两个节点的最低公共祖先&#xff0c; 一共分为两小题&#xff1a; 题目一&#xff1a;二叉搜索树的最近公共祖先题目二&#xff1a;二叉树的最近公共祖先 2. 题目1&#x…

目标检测 pytorch复现SSD目标检测项目

目标检测 pytorch复现SSD目标检测项目 0、简介1、模型整体框架&#xff08;以VGG16为特征提取网络&#xff09;3、默认框&#xff08;default box&#xff09;的生成--相当于Faster-RCNN中生成的anchor4、预测层的实现原理&#xff1a;5、正负样本的选取6、损失的计算原理6、以…

SpringCloud-9、Sleuth+Zipkin

先吐槽下csdn&#xff0c;编辑器不知道怎么回事&#xff0c;快捷键一下就没有&#xff0c;现在用起来糟心 --- - 这些都用不了&#xff0c;求帮助。 基本介绍 Sleuth:分布式服务跟踪组件 /ZipKin Sleuth/ZipKin-搭建链路监控实例 官网&#xff1a;GitHub - spring-cloud/s…

【移动端网页布局】移动端网页布局基础概念 ⑦ ( 在 PhotoShop 中使用 Cutterman 切二倍图 | 使用二倍图作为背景图像 )

文章目录 一、在 PhotoShop 中使用 Cutterman 切二倍图二、使用二倍图作为背景图像 一、在 PhotoShop 中使用 Cutterman 切二倍图 参考 【CSS】PhotoShop 切图 ③ ( PhotoShop 切图插件 - Cutterman | 下载、安装、启动、注册、登录 Cutterman - 切图神奇 插件 | 使用插件进行切…