当前位置: 首页 > article >正文

鸿蒙ArkUI之相对布局容器(RelativeContainer)实战之狼人杀布局,详细介绍相对布局容器的用法,附上代码,以及效果图

在鸿蒙应用开发中,若是遇到布局相对复杂的场景,往往需要嵌套许多层组件,去还原UI图的效果,若是能够掌握相对布局容器的使用,对于复杂的布局场景,可直接减少组件嵌套,且随心所欲完成复杂场景的布局。

官方地址:

RelativeContainer-行列与堆叠-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者

 关键属性

RelativeContainer能够帮我们随心所欲完成布局的关键在于,子组件可以通过alignRules这个属性去设置和什么什么组件对齐,通过锚点,去向某一个组件对齐,比如,父组件RelativeContainer()组件,它的锚点必须是:__container__,其他的组件可以通过设置id(接收字符串自定义)的方式来锁定锚点,下面这些参数,就是alignRules属性接收的参数。

名称类型描述
left{ anchor: string, align: HorizontalAlign }

设置左对齐参数。

- anchor:设置作为锚点的组件的id值。

- align:设置相对于锚点组件的对齐方式。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

right{ anchor: string, align: HorizontalAlign }

设置右对齐参数。

- anchor:设置作为锚点的组件的id值。

- align:设置相对于锚点组件的对齐方式。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

middle{ anchor: string, align: HorizontalAlign }

设置横向居中对齐方式的参数。

- anchor:设置作为锚点的组件的id值。

- align:设置相对于锚点组件的对齐方式。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

top{ anchor: string, align: VerticalAlign }

设置顶部对齐的参数。

- anchor:设置作为锚点的组件的id值。

- align:设置相对于锚点组件的对齐方式。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

bottom{ anchor: string, align: VerticalAlign }

设置底部对齐的参数。

- anchor:设置作为锚点的组件的id值。

- align:设置相对于锚点组件的对齐方式。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

center{ anchor: string, align: VerticalAlign }

设置纵向居中对齐方式的参数。

元服务API: 从API version 11开始,该接口支持在元服务中使用。

 用法

下面代码块所示:在RelativeContainer中有一个子组件,它的alignRules设置了顶部对齐RelativeContainer容器的顶部,左边对齐RelativeContainer的左边,为啥是RelativeContainer,因为,对齐的锚点是__contanier__,它就代表RelativeContainer容器,像其他子组件若是要向这个子组件对齐,就可以通过,这个组件绑定的id(img1)作为锚点,设置对齐方式

  RelativeContainer() {Column({ space: 2 }) {Image($r('app.media.nvwu')).height(40).width(40).borderRadius(20)Text('女巫').fontWeight(700).fontSize(12)}.id('img1').alignRules({top: { anchor: '__container__', align: VerticalAlign.Top }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 80, left: 15 })}

 像下面这个代码块,img2这个组件,就是相对img1,和RelativeContainer设置的对齐方式

 RelativeContainer() {Text('狼人杀').fontSize(20).fontWeight(700).alignRules({middle: { anchor: '__container__', align: HorizontalAlign.Center }}).margin({ top: 20 })Column({ space: 2 }) {Image($r('app.media.nvwu')).height(40).width(40).borderRadius(20)Text('女巫').fontWeight(700).fontSize(12)}.id('img1').alignRules({top: { anchor: '__container__', align: VerticalAlign.Top }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 80, left: 15 })Column({ space: 2 }) {Image($r('app.media.langren')).height(40).width(40).borderRadius(20)Text('狼人').fontWeight(700).fontSize(12)}.id('img2').alignRules({top: { anchor: 'img1', align: VerticalAlign.Bottom }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 20, left: 15 })}

注意点

加了组件,就必须给它设置对齐方式否则,组件将默认堆积在容器的左上角,组件margin的方向,也会跟着对齐方式的方向走,比如img2的上边,是对着img1的下边,img2的margin({top:10}) 就会对着img1的下边走10vp

完整代码

下面是一个简单的布局,给RelativeContainer的一级子组件都加上了id,也调整了对齐方式,img1到img4的左边,相对RelativeContainer的左边对齐,img5到img8的右边相对于RelativeContainer的右边对齐,img1的顶部相对于RelativeContainer的顶部对齐,img2到img4的顶部相对于前一个img的底部对齐,img5的顶部相对于RelativeContainer的顶部对齐,img6到img8的顶部相对于前一个img的底部对齐。

@Preview
@Component
export struct RelativeContainerCase {build() {NavDestination() {Column({ space: 20 }) {RelativeContainer() {Text('狼人杀').fontSize(20).fontWeight(700).alignRules({middle: { anchor: '__container__', align: HorizontalAlign.Center }}).margin({ top: 20 })Column({ space: 2 }) {Image($r('app.media.nvwu')).height(40).width(40).borderRadius(20)Text('女巫').fontWeight(700).fontSize(12)}.id('img1').alignRules({top: { anchor: '__container__', align: VerticalAlign.Top }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 80, left: 15 })Column({ space: 2 }) {Image($r('app.media.langren')).height(40).width(40).borderRadius(20)Text('狼人').fontWeight(700).fontSize(12)}.id('img2').alignRules({top: { anchor: 'img1', align: VerticalAlign.Bottom }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 20, left: 15 })Column({ space: 2 }) {Image($r('app.media.lieren')).height(40).width(40).borderRadius(20)Text('猎人').fontWeight(700).fontSize(12)}.id('img3').alignRules({top: { anchor: 'img2', align: VerticalAlign.Bottom }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 20, left: 15 })Column({ space: 2 }) {Image($r("app.media.pingmin")).height(40).width(40).borderRadius(20)Text('平民').fontWeight(700).fontSize(12)}.id('img4').alignRules({top: { anchor: 'img3', align: VerticalAlign.Bottom }, left: { anchor: '__container__', align: HorizontalAlign.Start }}).margin({ top: 20, left: 15 })Column({ space: 2 }) {Image($r('app.media.yvyanjia')).height(40).width(40).borderRadius(20)Text('预言家').fontWeight(700).fontSize(12)}.id('img5').alignRules({top: { anchor: '__container__', align: VerticalAlign.Top }, right: { anchor: '__container__', align: HorizontalAlign.End }}).margin({ top: 80, right: 15 })Column({ space: 2 }) {Image($r('app.media.pingmin')).height(40).width(40).borderRadius(20)Text('平民').fontWeight(700).fontSize(12)}.id('img6').alignRules({top: { anchor: 'img5', align: VerticalAlign.Bottom }, right: { anchor: '__container__', align: HorizontalAlign.End }}).margin({ top: 20, right: 15 })Column({ space: 2 }) {Image($r('app.media.langren')).height(40).width(40).borderRadius(20)Text('狼人').fontWeight(700).fontSize(12)}.id('img7').alignRules({top: { anchor: 'img6', align: VerticalAlign.Bottom }, right: { anchor: '__container__', align: HorizontalAlign.End }}).margin({ top: 20, right: 15 })Column({ space: 2 }) {Image($r('app.media.langren')).height(40).width(40).borderRadius(20)Text('狼人').fontWeight(700).fontSize(12)}.id('img8').alignRules({top: { anchor: 'img7', align: VerticalAlign.Bottom }, right: { anchor: '__container__', align: HorizontalAlign.End }}).margin({ top: 20, right: 15 })}.borderRadius(10).backgroundColor('#ccc')}.justifyContent(FlexAlign.Center).height('100%').width('100%')}.height('100%').width('100%').title('展示RelativeContainer')}
}@Builder
function RelativeContainerCaseBuilder() {RelativeContainerCase()
}

使用RelativeContainer的好处

对于这种布局,可以使用线性布局来展示,比如:两个Column,或者四个Row,那么用RelativeContainer的好处在哪?

如果使用线性布局,就会多出是组件的嵌套,影响渲染的性能,使用RelativeContainer,可以直接将组件树拍平,提升渲染性能,对于更加复杂的场景,使用RelativeContainer更是可以做到随心所欲布局,只要对照UI设计稿,把控好距离,设置id,我的组件想放那块就放哪块,不需要像线性布局那样考虑如何嵌套才能达到UI效果

 效果展示

 

相关文章:

鸿蒙ArkUI之相对布局容器(RelativeContainer)实战之狼人杀布局,详细介绍相对布局容器的用法,附上代码,以及效果图

在鸿蒙应用开发中,若是遇到布局相对复杂的场景,往往需要嵌套许多层组件,去还原UI图的效果,若是能够掌握相对布局容器的使用,对于复杂的布局场景,可直接减少组件嵌套,且随心所欲完成复杂场景的布…...

详解 Servlet 处理表单数据

Servlet 处理表单数据 1. 什么是 Servlet?2. 表单数据如何发送到 Servlet?2.1 GET 方法2.2 POST 方法 3. Servlet 如何接收表单数据?3.1 获取单个参数:getParameter()示例: 3.2 获取多个参数:getParameterV…...

Spring Cloud Gateway 如何将请求分发到各个服务

前言 在微服务架构中,API 网关(API Gateway)扮演着非常重要的角色。它负责接收客户端请求,并根据预定义的规则将请求路由到对应的后端服务。Spring Cloud Gateway 是 Spring 官方推出的一款高性能网关,支持动态路由、…...

解释器体系结构风格-笔记

解释器(Interpreter)是一种软件设计模式或体系结构风格,主要用于为语言(或表达式)定义其语法、语义,并通过解释器来解析和执行语言中的表达式。解释器体系结构风格广泛应用于编程语言、脚本语言、规则引擎、…...

线程函数库

pthread_create函数 pthread_create 是 POSIX 线程库&#xff08;pthread&#xff09;中的一个函数&#xff0c;用于创建一个新的线程。 头文件 #include <pthread.h> 函数原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*s…...

[C]基础13.深入理解指针(5)

博客主页&#xff1a;向不悔本篇专栏&#xff1a;[C]您的支持&#xff0c;是我的创作动力。 文章目录 0、总结1、sizeof和strlen的对比1.1 sizeof1.2 strlen1.3 sizeof和strlen的对比 2、数组和指针笔试题解析2.1 一维数组2.2 字符数组2.2.1 代码12.2.2 代码22.2.3 代码32.2.4 …...

OpenCV 图形API(60)颜色空间转换-----将图像从 YUV 色彩空间转换为 RGB 色彩空间函数YUV2RGB()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将图像从 YUV 色彩空间转换为 RGB。 该函数将输入图像从 YUV 色彩空间转换为 RGB。Y、U 和 V 通道值的常规范围是 0 到 255。 输出图像必须是 8…...

11.原型模式:思考与解读

原文地址:原型模式&#xff1a;思考与解读 更多内容请关注&#xff1a;7.深入思考与解读设计模式 引言 在软件开发中&#xff0c;尤其是当需要创建大量相似对象时&#xff0c;你是否遇到过这样的情况&#xff1a;每次创建新对象时&#xff0c;是否都需要重新初始化一些复杂的…...

深度解析 Java 泛型通配符 `<? super T>` 和 `<? extends T>`

Java 泛型中的通配符 ? 与 super、extends 关键字组合形成的 <? super T> 和 <? extends T> 是泛型系统中最重要的概念之一&#xff0c;也是许多开发者感到困惑的地方。本文将全面剖析它们的语义、使用场景和设计原理。 一、基础概念回顾 1. 泛型通配符 ? ?…...

hbuilderx云打包生成的ipa文件如何上架

使用hbuilderx打包&#xff0c;会遇到一个问题。开发的ios应用&#xff0c;需要上架到app store&#xff0c;因此&#xff0c;就需要APP store的签名证书&#xff0c;并且还需要一个像xcode那样的工具来上架app store。 我们这篇文章说明下&#xff0c;如何在windows电脑&…...

Golang | 位运算

位运算比常规运算快&#xff0c;常用于搜索引擎的筛选功能。例如&#xff0c;数字除以二等价于向右移位&#xff0c;位移运算比除法快。...

天能资管(SkyAi):大数据洞察市场,引领投资新风向

在金融市场的浩瀚海洋中,信息如同灯塔,指引着投资者前行的方向。谁能更准确地把握市场动态和趋势,谁就能在激烈的市场竞争中占据先机。天能资管(SkyAi),作为卡塔尔投资局(QIA)旗下的科技先锋,凭借其强大的大数据处理能力与前沿的技术架构,为全球投资者提供了前所未有的市场洞察…...

产品动态|千眼狼sCMOS科学相机捕获单分子荧光信号

单分子荧光成像技术&#xff0c;作为生物分子动态研究的关键工具&#xff0c;对捕捉微弱信号要求严苛。传统EMCCD相机因成本高昂&#xff0c;动态范围有限&#xff0c;满阱容量低等问题&#xff0c;制约单分子研究成果产出效率。 千眼狼精准把握科研需求与趋势&#xff0c;自研…...

基于大牛直播SDK的Android屏幕扬声器采集推送RTMP技术解析

在移动互联网时代&#xff0c;直播技术的应用越来越广泛&#xff0c;而屏幕采集推送作为直播内容源的重要获取方式之一&#xff0c;也备受关注。本文将基于大牛直播SDK&#xff0c;深入剖析如何实现Android屏幕采集推送RTMP的完整流程&#xff0c;带你领略其背后的技术细节与魅…...

Linux防火墙工具UFW介绍

UFW(Uncomplicated Firewall)是 Ubuntu、Debian 等 Debian 系 Linux 发行版默认的防火墙管理工具,基于 iptables 开发,旨在通过简化的命令行接口(CLI)降低防火墙配置门槛,适合新手和简单场景。 核心目标:让用户无需深入理解 iptables 的 “表 - 链” 结构,通过直观的命…...

k8s 手动续订证书

注意:如果是高可用环境,本文的操作需要在所有控制节点都执行。 查看证书是否过期 kubeadm certs check-expirationkubeadm certs renew可以续订任何特定证书,或者使用子命令all可以续订所有证书: kubeadm certs renew all使用 kubeadm 构建的集群通常会将admin.conf证书复…...

vc++ 如何调用poco库

1. 下载并安装 Poco 库 你可以从 Poco 的官方网站&#xff08;POCO C Libraries - Simplify C Development &#xff09;下载其源代码压缩包。下载完成后&#xff0c;按照下面的步骤进行编译和安装&#xff1a; 解压源代码&#xff1a;把下载的压缩包解压到指定目录。配置编译…...

Hot100方法及易错点总结2

本文旨在记录做hot100时遇到的问题及易错点 五、234.回文链表141.环形链表 六、142. 环形链表II21.合并两个有序链表2.两数相加19.删除链表的倒数第n个节点 七、24.两两交换链表中的节点25.K个一组翻转链表(坑点很多&#xff0c;必须多做几遍)138.随机链表的复制148.排序链表 N…...

网络:手写HTTP

目录 一、HTTP是应用层协议 二、HTTP服务器 三、HTTP服务 认识请求中的uri HTTP支持默认首页 响应 功能完善 套接字复用 一、HTTP是应用层协议 HTTP下层是TCP协议&#xff0c;站在TCP的角度看&#xff0c;要提供的服务是HTTP服务。 这是在原来实现网络版计算器时&am…...

C++[类和对象][3]

C[类和对象][3] 赋值运算符的重载(operator) 1.是一个默认成员函数,重载必须为成员函数,用于两个已经存在的对象,(d1d3赋值重载)(Stack d4d1拷贝构造(因为d4未存在,初始化)) 2.建议写成引用返回提高效率,可以连续赋值重载 3.没有写的时候会自动生成,完成值拷贝/浅拷贝对(对于…...

【计算机视觉】CV实战项目 - 基于YOLOv5的人脸检测与关键点定位系统深度解析

基于YOLOv5的人脸检测与关键点定位系统深度解析 1. 技术背景与项目意义传统方案的局限性YOLOv5多任务方案的优势 2. 核心算法原理网络架构改进关键点回归分支损失函数设计 3. 实战指南&#xff1a;从环境搭建到模型应用环境配置数据准备数据格式要求数据目录结构 模型训练配置文…...

【python】如何将python程序封装为cpython的库

python程序在发布时&#xff0c;往往会打包为cpython的库&#xff0c;并且根据应用服务器的不同架构&#xff08;x86/aarch64&#xff09;&#xff0c;以及python的不同版本&#xff0c;封装的输出类型也是非常多。本文介绍不同架构指定python下的代码打包方式&#xff1a; 首…...

【人工智能】DeepSeek 的开源生态:释放 AI 潜能的社区协同与技术突破

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 DeepSeek 作为中国 AI 领域的先锋,以其高效的混合专家模型(MoE)和彻底的开源策略,在全球 AI 社区掀起波澜。本文深入剖析 DeepSeek 的开…...

【差分隐私】假设检验的视角(高斯差分隐私)

在差分隐私中&#xff0c;假设检验的框架被用来量化攻击者通过机制输出区分两个相邻数据集 S S S 和 S ′ S S′ 的难度。这种区分的根本困难直接反映了隐私保护强度。以下是对问题的详细解释&#xff1a; 1. 假设检验的基本设定 原假设 H 0 H_0 H0​&#xff1a;数据集为 …...

计算机组成原理 课后练习

例一&#xff1a; 例二&#xff1a; 1. 原码一位乘 基本原理 原码是一种直接表示数值符号和大小的方式&#xff1a;最高位为符号位&#xff08;0表示正&#xff0c;1表示负&#xff09;&#xff0c;其余位表示数值的绝对值。原码一位乘的核心思想是逐位相乘&#xff0c;并通…...

pytorch手动调整学习率

文章目录 1. 为什么引入学习率衰减&#xff1f;2. 针对不同层设置不一样的学习率3. 手动更新学习率4. 使用学习率调度器5. 推荐做法 在前面的文章中&#xff0c;介绍了各种学习率。在此&#xff0c;将进行拓展&#xff0c;学习如何手动更新学习率&#xff08;即不使用pytorch自…...

SVN仓库突然没有权限访问

如果svn仓库突然出现无法访问的情况&#xff0c;提示没有权限&#xff0c;所有账号都是如此&#xff0c;新创建的账号也不行。 并且会突然提示要输入账号密码。 出现这个情况时&#xff0c;大概率库里面的文件有http或者https的字样&#xff0c;因为单独给该文件添加权限导致…...

【Qt】文件

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Qt 目录 一&#xff1a;&#x1f525; Qt 文件概述 二&#xff1a;&#x1f525; 输入输出设备类 三&#xff1a;&#x1f525; 文件读写类 四&#xff1a;&#x1f525; 文件和目录信息类 五&…...

7.DJI-PSDK:psdk负载应用固件升级(基于RTOS)

DJI-PSDK:psdk负载应用固件升级(基于RTOS): 在单片机应用程序开发阶段,我们可以借助keil5和J-LINK来直接下载应用程序进行开发和调试, 但在产品交付之后,我们对应用程序做了改动和升级,是断然不可能采用这种方式的,我们应该将新版本的程序固件打包发给客户, 能够方便用…...

ArrayUtils:数组操作的“变形金刚“——让你的数组七十二变

各位数组操控师们好&#xff01;今天给大家带来的是Apache Commons Lang3中的ArrayUtils工具类。这个工具就像数组界的"孙悟空"&#xff0c;能让你的数组随心所欲地变大、变小、变长、变短&#xff0c;再也不用对着原生数组的"死板"叹气了&#xff01; 一…...