news 2026/4/27 17:18:26

HarmonyOS 自定义组件与布局实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS 自定义组件与布局实践

网罗开发(小红书、快手、视频号同名)

大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
    • 自定义组件的基本写法
      • 无参组件
      • 带参组件:@Prop 与默认值
    • @Builder 复用 UI 片段
      • 无参 Builder
      • 带尾随闭包的 Builder(@BuilderParam)
    • 常用布局与属性
      • Column / Row 的对齐与间距
      • Flex 弹性布局
      • Stack 堆叠
      • 占满剩余空间
    • 尺寸与约束
    • 总结

前言

ArkTS 声明式 UI 除了使用系统内置的 Text、Button、Column、Row 等,还需要把可复用的 UI 拆成自定义组件,并用合理的布局和 @Builder 减少重复代码。自定义组件和布局用得好,页面结构清晰、维护成本低;用得不好,容易变成「一大坨 build()」或属性传参混乱。

本文只讲自定义组件、@Builder、以及常用布局的关键写法和注意点,不贴完整页面 Demo。

自定义组件的基本写法

自定义组件就是一个用@Component装饰的 struct,内部有build()返回一棵 UI 树,外部通过构造函数传参。

无参组件

@Componentstruct CardTitle{build(){Row(){Text('标题').fontSize(18).fontColor('#333333')Blank()Text('更多').fontSize(14).fontColor('#999999')}.width('100%').padding(12)}}

使用时直接当子节点写:

Column(){CardTitle()// 其他内容}

带参组件:@Prop 与默认值

通过构造函数传参,用@Prop接收(只读),可带默认值:

@Componentstruct ItemCard{@Proptitle:string='默认标题'@Propdesc:string=''build(){Column(){Text(this.title).fontSize(16).fontWeight(FontWeight.Medium)if(this.desc){Text(this.desc).fontSize(14).fontColor('#666666').margin({top:4})}}.alignItems(HorizontalAlign.Start).width('100%').padding(12).backgroundColor('#F5F5F5').borderRadius(8)}}

使用:

ItemCard({title:'卡片一',desc:'描述文字'})ItemCard({title:'仅标题'})// desc 用默认值 ''

若需要「父改子、子改父」双向同步,用@Link配合父组件的$xxx传引用。

@Builder 复用 UI 片段

同一段 UI 在多个地方出现时,不必再拆一个组件,可用@Builder定义「UI 片段」,在 build 里多次调用。

无参 Builder

@Entry@Componentstruct Page{@BuildersectionTitle(title:string){Text(title).fontSize(20).fontWeight(FontWeight.Bold).margin({bottom:12})}build(){Column(){this.sectionTitle('第一部分')// 内容...this.sectionTitle('第二部分')// 内容...}}}

sectionTitle只在当前组件内使用,参数直接写在方法参数里。

带尾随闭包的 Builder(@BuilderParam)

若希望「调用方传入一块自定义 UI」,可用@BuilderParam定义占位,调用时用尾随闭包传入:

@Componentstruct ContainerCard{@BuilderParamheader:()=>void=()=>{}@BuilderParamcontent:()=>void=()=>{}build(){Column(){this.header()this.content()}.width('100%').backgroundColor('#FFF').borderRadius(8).padding(12)}}// 使用ContainerCard(){Column(){Text('自定义头部')}.width('100%').height(40)Column(){Text('自定义内容')}}

注意:ArkTS 中 @BuilderParam 的写法与调用方式以当前 API 为准,有时需要配合@Builder或特定语法传递「一块 build 函数」。

常用布局与属性

Column / Row 的对齐与间距

  • Column.alignItems(HorizontalAlign.Start/Center/End)控制子项水平对齐;.justifyContent(FlexAlign.Start/Center/SpaceBetween)控制垂直方向分布
  • Row.alignItems(VerticalAlign.Top/Center/Bottom).justifyContent(FlexAlign.SpaceBetween)同理,方向与 Column 对调

子项之间加间距可用.margin({ top: 8 })或外层用.gap(8)(若 API 支持)。

Flex 弹性布局

需要「按比例占宽」或「换行」时可用 Flex:

Flex({direction:FlexDirection.Row,wrap:FlexWrap.Wrap}){ForEach(this.tags,(item:string)=>{Text(item).fontSize(12).padding({left:8,right:8,top:4,bottom:4}).backgroundColor('#EEEEEE').borderRadius(4)})}.width('100%').justifyContent(FlexAlign.Start)

FlexWrap.Wrap表示子项排不下时换行,适合标签列表。

Stack 堆叠

用于「底层 + 上层叠加」(如图片 + 蒙层、图标 + 角标):

Stack(){Image($r('app.media.bg')).width('100%').height(120)Column(){Text('角标').fontSize(10).backgroundColor('#FF0000').padding(2)}.position({x:'80%',y:8})}.width('100%').height(120)

子节点顺序即叠放顺序,后写的在上层;.position()用于绝对定位。

占满剩余空间

Column 中若希望某一块「把剩余高度占满」,可给该子节点.layoutWeight(1)(在 Flex 或支持 layoutWeight 的容器中)。例如:

Column(){Text('顶部固定')List(){...}.layoutWeight(1)// 占满剩余空间.scrollBar(BarState.Off)}.height('100%')

这样列表会占据除顶部外的全部空间,并正常滚动。

尺寸与约束

  • 固定宽高.width(100).height(50).width('100%').height('100%')
  • 最大/最小.constraintSize({ minWidth: 100, maxWidth: 300 })等(以当前 API 为准)
  • 宽高比:部分组件支持.aspectRatio(16/9),用于图片、视频等

避免在根 Column/Row 上不设宽高却期望「铺满」,否则可能布局异常;至少保证根节点有明确尺寸或layoutWeight

总结

  • 自定义组件@Component+build(),通过构造函数和@Prop/@Link传参,便于复用和拆页。
  • @Builder:同一组件内复用 UI 片段;@BuilderParam用于「由调用方传入一块 UI」的容器型组件。
  • 布局:Column/Row 负责线性排布与对齐;Flex 负责弹性、换行;Stack 负责堆叠;合理使用layoutWeight分配剩余空间。

按「页面 → 区块 → 小组件」的层级拆分,再配合 Builder 抽公共样式,就能在保持结构清晰的前提下减少重复代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 18:27:35

大模型代理推理完全指南:从被动预测到主动行动的范式转变

如果在 2023 年,我们还在为 ChatGPT 能写出一首打油诗而惊叹,那么到了 2026 年的今天,单纯的“文本生成”已经无法满足我们对 AGI 的胃口了。我们痛苦地发现:即便模型参数大到离谱,它依然是一个“被动”的预言家——它…

作者头像 李华
网站建设 2026/4/21 23:29:30

企业选对 AI 人力资源管理系统的秘诀:认准 “真智能” 核心特质

在数字化转型加速的当下,AI 人力资源管理系统已成为企业优化 HR 流程、提升效率的重要工具。但市场上产品良莠不齐,不少标注 “智能” 的系统仅停留在基础自动化层面,并非真正意义上的智能应用。对于 HR 而言,选对一款真正智能的 …

作者头像 李华
网站建设 2026/4/23 18:52:53

智能反射表面的建模与优化设计研究

智能反射表面的建模与优化设计研究 第一章 绪论 随着无线通信向6G演进,频谱资源紧张、信道环境复杂、能耗过高成为核心瓶颈。智能反射表面(IRS, Intelligent Reflecting Surface)作为一种革命性技术,通过在二维平面上集成大量低…

作者头像 李华
网站建设 2026/4/20 9:26:33

【四个场景测试】源文件编码GBK

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 固定测试前提一、逐场景解析:判定你的描述修正补充二、你的整体测试思想总结三、四种测试场景标准化对比表四、关键补充修正与说明总结 靠你自己结合我上…

作者头像 李华
网站建设 2026/4/17 12:50:30

航空安全员报考材料处理全攻略:证件照规范、材料压缩与上传指南

航空安全员是维护民航空中安全、保障航班运行秩序的关键岗位,在招聘报名、资格审核、执照办理、定期复训等环节,对证件照、身份证明、资质材料的格式与清晰度要求极高。很多考生因照片尺寸不符、文件体积超标、PDF排版混乱、印章模糊被系统自动驳回&…

作者头像 李华