52.[HarmonyOS NEXT RelativeContainer案例九] 灵活比例布局:链中节点权重分配技术详解

简介: 在现代UI设计中,按照特定比例分配空间的布局需求非常常见,例如黄金分割比例的内容区域、按照特定比例分配的多列布局等。HarmonyOS NEXT的RelativeContainer组件提供了链中节点权重(chainWeight)功能,能够按照指定的权重比例分配链中组件的空间,实现灵活的比例布局。本教程将详细讲解如何利用RelativeContainer的链中节点权重功能实现灵活的比例布局,帮助你掌握这一强大的布局技术。


项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star

效果演示


1. 引言

在现代UI设计中,按照特定比例分配空间的布局需求非常常见,例如黄金分割比例的内容区域、按照特定比例分配的多列布局等。HarmonyOS NEXT的RelativeContainer组件提供了链中节点权重(chainWeight)功能,能够按照指定的权重比例分配链中组件的空间,实现灵活的比例布局。本教程将详细讲解如何利用RelativeContainer的链中节点权重功能实现灵活的比例布局,帮助你掌握这一强大的布局技术。

2. 链中节点权重(ChainWeight)概述

链中节点权重是RelativeContainer链式布局的一个高级特性,它允许开发者为链中的每个组件分配权重值,系统会根据这些权重值按比例分配可用空间。权重值可以是任意正数,组件获得的空间比例等于其权重值除以所有组件权重值的总和。

2.1 链中节点权重的特性

  • 比例分配:根据权重比例分配空间
  • 灵活调整:通过调整权重值实现不同的分配比例
  • 链式样式兼容:可以与不同的链式样式(ChainStyle)结合使用
  • 动态调整:可以通过状态变量动态调整权重值

3. 案例分析:权重布局

3.1 完整代码

@Component
export struct WeightedLayout {
    build() {
        RelativeContainer() {
            // 左侧区域
            Column() {
                Text('左侧区域')
                    .fontSize(16)
                    .fontColor('#ffffff')
            }
            .width('100%')
            .height('100%')
            .backgroundColor('#007DFF')
            .justifyContent(FlexAlign.Center)
            .id("leftArea")
            .alignRules({
                left: { anchor: "parent", align: HorizontalAlign.Start },
                top: { anchor: "parent", align: VerticalAlign.Top },
                bottom: { anchor: "parent", align: VerticalAlign.Bottom }
            })
            // 中间区域
            Column() {
                Text('中间区域')
                    .fontSize(16)
                    .fontColor('#ffffff')
            }
            .width('100%')
            .height('100%')
            .backgroundColor('#FF7D00')
            .justifyContent(FlexAlign.Center)
            .id("middleArea")
            .alignRules({
                left: { anchor: "leftArea", align: HorizontalAlign.End },
                top: { anchor: "parent", align: VerticalAlign.Top },
                bottom: { anchor: "parent", align: VerticalAlign.Bottom }
            })
            // 右侧区域
            Column() {
                Text('右侧区域')
                    .fontSize(16)
                    .fontColor('#ffffff')
            }
            .width('100%')
            .height('100%')
            .backgroundColor('#7D00FF')
            .justifyContent(FlexAlign.Center)
            .id("rightArea")
            .alignRules({
                left: { anchor: "middleArea", align: HorizontalAlign.End },
                right: { anchor: "parent", align: HorizontalAlign.End },
                top: { anchor: "parent", align: VerticalAlign.Top },
                bottom: { anchor: "parent", align: VerticalAlign.Bottom }
            })
        }
        .chainMode([
            {
                id: "horizontalChain",
                direction: Direction.HORIZONTAL,
                style: ChainStyle.SPREAD,
                components: ["leftArea", "middleArea", "rightArea"],
                chainWeights: [1, 2, 1] // 1:2:1的比例
            }
        ])
        .width('100%')
        .height(200)
    }
}

3.2 代码详解

3.2.1 RelativeContainer容器设置

RelativeContainer() {
    // 子组件
}
.chainMode([
    {
        id: "horizontalChain",
        direction: Direction.HORIZONTAL,
        style: ChainStyle.SPREAD,
        components: ["leftArea", "middleArea", "rightArea"],
        chainWeights: [1, 2, 1] // 1:2:1的比例
    }
])
.width('100%')
.height(200)

这部分代码创建了一个RelativeContainer容器,并设置了以下属性:

属性

说明

chainMode

[...]

定义链式布局数组

width

'100%'

容器宽度为父容器的100%

height

200

容器高度为200vp

这里的关键是chainMode属性,它定义了一个水平链:

  • id: "horizontalChain" - 链的唯一标识符
  • direction: Direction.HORIZONTAL - 链的方向为水平
  • style: ChainStyle.SPREAD - 链的样式为均匀分布
  • components: ["leftArea", "middleArea", "rightArea"] - 链中包含的组件ID数组
  • chainWeights: [1, 2, 1] - 链中组件的权重数组,按照1:2:1的比例分配空间

这个水平链将三个区域组件连接起来,并根据指定的权重比例分配空间,使中间区域的宽度是左右区域的两倍。

3.2.2 左侧区域设置

Column() {
    Text('左侧区域')
        .fontSize(16)
        .fontColor('#ffffff')
}
.width('100%')
.height('100%')
.backgroundColor('#007DFF')
.justifyContent(FlexAlign.Center)
.id("leftArea")
.alignRules({
    left: { anchor: "parent", align: HorizontalAlign.Start },
    top: { anchor: "parent", align: VerticalAlign.Top },
    bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})

左侧区域的关键属性设置:

属性

说明

width

'100%'

宽度为父容器的100%(实际宽度将由链中权重决定)

height

'100%'

高度为父容器的100%

backgroundColor

'#007DFF'

背景色为蓝色

justifyContent

FlexAlign.Center

内容居中对齐

id

"leftArea"

组件的唯一标识符,用于链式布局引用

alignRules

{...}

对齐规则

这里的关键点是为左侧区域设置了一个唯一的ID "leftArea",这样链式布局就可以引用它。同时,通过alignRules将其左侧对齐到父容器的左侧,顶部和底部分别对齐到父容器的顶部和底部,使其占据容器的整个高度。

3.2.3 中间区域设置

Column() {
    Text('中间区域')
        .fontSize(16)
        .fontColor('#ffffff')
}
.width('100%')
.height('100%')
.backgroundColor('#FF7D00')
.justifyContent(FlexAlign.Center)
.id("middleArea")
.alignRules({
    left: { anchor: "leftArea", align: HorizontalAlign.End },
    top: { anchor: "parent", align: VerticalAlign.Top },
    bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})

中间区域的关键属性设置:

属性

说明

width

'100%'

宽度为父容器的100%(实际宽度将由链中权重决定)

height

'100%'

高度为父容器的100%

backgroundColor

'#FF7D00'

背景色为橙色

justifyContent

FlexAlign.Center

内容居中对齐

id

"middleArea"

组件的唯一标识符,用于链式布局引用

alignRules

{...}

对齐规则

中间区域的左侧对齐到左侧区域的右侧,顶部和底部分别对齐到父容器的顶部和底部。

3.2.4 右侧区域设置

Column() {
    Text('右侧区域')
        .fontSize(16)
        .fontColor('#ffffff')
}
.width('100%')
.height('100%')
.backgroundColor('#7D00FF')
.justifyContent(FlexAlign.Center)
.id("rightArea")
.alignRules({
    left: { anchor: "middleArea", align: HorizontalAlign.End },
    right: { anchor: "parent", align: HorizontalAlign.End },
    top: { anchor: "parent", align: VerticalAlign.Top },
    bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})

右侧区域的关键属性设置:

属性

说明

width

'100%'

宽度为父容器的100%(实际宽度将由链中权重决定)

height

'100%'

高度为父容器的100%

backgroundColor

'#7D00FF'

背景色为紫色

justifyContent

FlexAlign.Center

内容居中对齐

id

"rightArea"

组件的唯一标识符,用于链式布局引用

alignRules

{...}

对齐规则

右侧区域的左侧对齐到中间区域的右侧,右侧对齐到父容器的右侧,顶部和底部分别对齐到父容器的顶部和底部。

4. 链中节点权重的高级应用

4.1 不同链式样式下的权重效果

链中节点权重在不同的链式样式下有不同的效果:

链式样式

权重效果

ChainStyle.SPREAD

按权重比例分配所有可用空间

ChainStyle.SPREAD_INSIDE

按权重比例分配除首尾组件外的可用空间

ChainStyle.PACKED

按权重比例分配组件之间的间距

4.2 黄金分割比例布局

可以使用黄金分割比例(约1:1.618)创建视觉上和谐的布局:

.chainMode([
    {
        id: "goldenRatioChain",
        direction: Direction.HORIZONTAL,
        style: ChainStyle.SPREAD,
        components: ["leftArea", "rightArea"],
        chainWeights: [1, 1.618] // 黄金分割比例
    }
])

4.3 垂直链中的权重分配

垂直链也支持权重分配:

.chainMode([
    {
        id: "verticalChain",
        direction: Direction.VERTICAL,
        style: ChainStyle.SPREAD,
        components: ["header", "content", "footer"],
        chainWeights: [1, 4, 1] // 1:4:1的比例
    }
])

4.4 动态权重

可以通过状态变量动态调整权重值,实现布局的动态变化:

@State leftWeight: number = 1;
@State middleWeight: number = 2;
@State rightWeight: number = 1;
// 在构建函数中
.chainMode([
    {
        id: "horizontalChain",
        direction: Direction.HORIZONTAL,
        style: ChainStyle.SPREAD,
        components: ["leftArea", "middleArea", "rightArea"],
        chainWeights: [this.leftWeight, this.middleWeight, this.rightWeight]
    }
])
// 在事件处理函数中
onExpandLeft() {
    this.leftWeight = 2;
    this.middleWeight = 1;
    this.rightWeight = 1;
}

5. 比例布局的最佳实践

5.1 常见的比例布局

以下是一些常见的比例布局及其实现方法:

布局类型

实现方法

等分布局

所有组件权重相等,如[1, 1, 1]

主次布局

主要区域权重大,次要区域权重小,如[2, 1]

黄金分割

按照黄金比例设置权重,如[1, 1.618]

自定义比例

根据设计需求设置特定比例,如[3, 5, 2]

5.2 响应式比例布局

可以根据屏幕尺寸动态调整比例:

@State screenWidth: number = 0;
// 在aboutToAppear生命周期函数中获取屏幕宽度
aboutToAppear() {
    this.screenWidth = px2vp(window.getWindowWidth());
}
// 根据屏幕宽度计算权重
getWeights() {
    if (this.screenWidth < 600) {
        return [1, 1]; // 窄屏幕使用1:1比例
    } else {
        return [1, 2]; // 宽屏幕使用1:2比例
    }
}

6. 实际应用场景

链中节点权重分配在以下场景中特别有用:

  1. 多列布局:按照特定比例分配多列的宽度
  2. 分割视图:创建可调整比例的分割视图
  3. 内容布局:按照视觉重要性分配内容区域
  4. 响应式设计:根据屏幕尺寸动态调整布局比例

7. 总结

链中节点权重分配是RelativeContainer链式布局的一个强大特性,特别适合创建按照特定比例分配空间的布局。

相关文章
|
7月前
|
监控 JavaScript 编译器
从“天书”到源码:HarmonyOS NEXT 崩溃堆栈解析实战指南
本文详解如何利用 hiAppEvent 监控并获取 sourcemap、debug so 等核心产物,剖析了 hstack 工具如何将混淆的 Native 与 ArkTS 堆栈还原为源码,助力开发者掌握异常分析方法,提升应用稳定性。
942 89
|
8月前
|
存储 缓存 5G
鸿蒙 HarmonyOS NEXT端云一体化开发-云存储篇
本文介绍用户登录后获取昵称、头像的方法,包括通过云端API和AppStorage两种方式,并实现上传头像至云存储及更新用户信息。同时解决图片缓存问题,添加上传进度提示,支持自动登录判断,提升用户体验。
342 1
|
8月前
|
存储 负载均衡 数据库
鸿蒙 HarmonyOS NEXT端云一体化开发-云函数篇
本文介绍基于华为AGC的端云一体化开发流程,涵盖项目创建、云函数开通、应用配置及DevEco集成。重点讲解云函数的编写、部署、调用与传参,并涉及环境变量设置、负载均衡、重试机制与熔断策略等高阶特性,助力开发者高效构建稳定云端服务。
752 1
鸿蒙 HarmonyOS NEXT端云一体化开发-云函数篇
|
8月前
|
存储 JSON 数据建模
鸿蒙 HarmonyOS NEXT端云一体化开发-云数据库篇
云数据库采用存储区、对象类型、对象三级结构,支持灵活的数据建模与权限管理,可通过AGC平台或本地项目初始化,实现数据的增删改查及端侧高效调用。
421 1
|
8月前
|
存储 开发者 容器
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
本文介绍了ArkTS语言中的Class类、泛型、接口、模块化、自定义组件及状态管理等核心概念,并结合代码示例讲解了对象属性、构造方法、继承、静态成员、访问修饰符等内容,同时涵盖了路由管理、生命周期和Stage模型等应用开发关键知识点。
578 1
鸿蒙 HarmonyOS NEXT星河版APP应用开发-ArkTS面向对象及组件化UI开发使用实例
|
8月前
鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段三
本文介绍了UI开发中的样式复用与组件构建技术,涵盖@Extend、@Styles和@Builder的使用方法,并通过Swiper轮播、Scroll滚动、Tabs导航等常用组件实现典型界面效果,结合生肖抽卡、小米轮播、回顶按钮等案例,展示实际应用技巧。
221 1
|
8月前
鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段二
本文介绍鸿蒙应用界面开发中的弹性布局(Flex)、绝对定位、层叠布局及ArkTS语法进阶,涵盖字符串拼接、类型转换、数组操作、条件与循环语句,并结合B站视频卡、支付宝首页等案例,深入讲解点击事件、状态管理与界面交互功能。
453 1
鸿蒙 HarmonyOS NEXT星河版APP应用开发-阶段二
|
8月前
鸿蒙应用开发从入门到实战(十六):线性布局案例
ArkUI提供了丰富的系统组件,用于制作鸿蒙原生应用APP的UI,本文通过简单案例演示如何使用Column和Row组件实现线性布局。
289 1
|
8月前
|
传感器 监控 安全
HarmonyOS NEXT 5.0 的星闪(NearLink)开发应用案例
V哥分享HarmonyOS NEXT 5.0星闪开发实战,涵盖智能车钥匙无感解锁与工业传感器监控。低延迟、高可靠,代码完整,速来学习!
1049 0
|
9月前
|
移动开发 网络协议 小程序
鸿蒙NEXT即时通讯/IM系统RinbowTalk v2.4版发布,基于MobileIMSDK框架、ArkTS编写
RainbowTalk是一套基于开源即时通讯讯IM框架 MobileIMSDK 的产品级鸿蒙NEXT端IM系统。纯ArkTS编写、全新开发,没有套壳、也没走捷径,每一行代码都够“纯血”。与姊妹产品RainbowChat和RainbowChat-Web 技术同源,历经考验。
377 1

热门文章

最新文章