HarmonyOS7 声明式 UI 入门:Column 与 Row 布局实战

📅 2026/7/12 10:44:10
HarmonyOS7 声明式 UI 入门:Column 与 Row 布局实战
文章目录前言先搞懂一件事什么是声明式代码实现Column竖着排从上到下核心代码Row横着排从左到右完整示例重点来了嵌套组合代码解析小白问答常见误区小白必踩完整可运行示例写一个登录页实现拆解写在最后前言我刚转到 HarmonyOS 那会儿最不习惯的就是它的 UI 写法。以前写界面是一行一行命令系统把这个按钮放到那里到了 ArkUI 这边你改成描述界面长什么样——剩下的交给框架去算。这篇文章我就用最朴素的大白话把Column和Row这两个最基础、也最常用的布局容器讲透。读完你就能自己摆出 90% 的静态页面。不需要任何前置基础跟着敲一遍就行。小建议下面每一段代码都建议你在 DevEco Studio 里新建一个 Page 实测光看是记不住的。先搞懂一件事什么是声明式说白了声明式就是你描述结果框架负责过程。比如你想让两个文字上下排列。命令式思维是先画第一个y 坐标加 20再画第二个。声明式思维是我这里有一个竖着排的容器里面放两个文字——至于它们具体坐标是多少你不用管。代码实现Column(){Text(第一行)Text(第二行)}这段代码的含义是建一个竖向容器里面依次放两个文本。运行出来两个文本自然就是上下的。就这么简单。Column竖着排从上到下Column是纵向布局容器子组件按书写顺序从上往下依次堆叠。它有三个最常用、也最容易混淆的属性我一个一个说。核心代码Column({space:12}){Text(手机号).fontSize(16)Text(密码).fontSize(16)Button(登录).width(100%)}.width(100%).alignItems(HorizontalAlign.Start).justifyContent(FlexAlign.Center)逐行拆解一下第 1 行Column({ space: 12 })space是子组件之间的间距这里设 12vp相当于每个元素之间自动留 12 像素的空隙不用你手动加 margin。第 2~4 行里面依次放手机号密码两个文本和一个登录按钮。注意 ArkUI 里子组件就直接写在Column() { ... }的大括号里没有额外的标签。第 5 行.width(100%)让这个 Column 占满父容器宽度。第 6 行.alignItems(HorizontalAlign.Start)控制水平方向的对齐。Start表示靠左。如果你写成Center就是水平居中。第 7 行.justifyContent(FlexAlign.Center)控制垂直方向的对齐。Center表示在竖向空间里居中。这里有个新手必踩的点alignItems管的是交叉轴justifyContent管的是主轴。对 Column 来说主轴是竖的交叉轴是横的。记住这句就够了。Row横着排从左到右Row和Column是一对区别只是方向Row 是从左到右横着排。完整示例Row({space:8}){Image($r(app.media.icon)).width(24).height(24)Text(我的订单).fontSize(16)Blank()// 弹簧把后面的内容顶到最右Text().fontColor(#999999)}.width(100%).padding(12)几个关键点第 1 行Row({ space: 8 })子组件之间水平间距 8vp。第 3 行Blank()是个占位弹簧它会自动把剩余空间吃掉于是后面的就被挤到了最右边。这是做左标题右箭头布局的标配技巧。第 5 行.padding(12)给整个 Row 内边距 12vp让内容不贴边。重点来了嵌套组合真实页面几乎都是 Column 和 Row 互相套。比如一个常见的列表项左边图标标题竖排右边箭头。代码解析Row(){Row(){Image($r(app.media.icon)).width(40).height(40)Column(){Text(标题文字).fontSize(16).fontWeight(FontWeight.Bold)Text(副标题说明).fontSize(12).fontColor(#999999)}.alignItems(HorizontalAlign.Start).margin({left:12})}.layoutWeight(1)// 占满左边剩余空间Text().fontColor(#999999)}.width(100%).padding(12)这里外层是 Row左内容 右箭头内层左边又是一个 Row图标 竖排文字的 Column。.layoutWeight(1)让内层 Row 把中间空间吃满箭头自然贴右。小白问答QColumn 和 Row 能不能无限嵌套能但别超过 4 层不然你自己都看不懂性能也亏。Qspace 和 margin 有什么区别space是容器给所有子元素之间统一加的空隙margin是单个元素自己向外撑的空白。想要统一间距用space更省事。Q为什么我设了 alignItems 没反应八成是你搞混了主轴和交叉轴。Column 的alignItems管水平Row 的alignItems管垂直别记反。常见误区小白必踩误区说明搞混主轴和交叉轴Column 的alignItems管水平、justifyContent管垂直Row 正好反过来。记反了对齐永远不对。space 和 margin 分不清space是容器给所有子元素统一加空隙margin是单个元素自己撑空白。想要均匀间距用space最省事。无脑嵌套Column/Row 套超过 4 层自己都看不懂性能也亏。能扁平就扁平。下面这段代码可以直接复制到 DevEco Studio 里运行。建议你边读边敲改一改文末「动手改一改」里的参数亲眼看看效果。完整可运行示例写一个登录页下面这个例子把前面所有知识点串起来。你新建一个 Page把整段粘进去就能跑。实现拆解// 完整登录页Column 竖向 Row 行内组合 状态绑定EntryComponentstruct LoginPage{Stateaccount:string// 账号State 让输入能驱动 UIStatepassword:string// 密码build(){Column({space:16}){// 整页竖向子元素间距 16vpText(欢迎登录).fontSize(24).fontWeight(FontWeight.Bold)// 账号行固定宽标签 输入框Row(){Text(账号).width(60)TextInput({placeholder:请输入手机号}).layoutWeight(1)// 输入框吃掉剩余宽度.onChange((v){this.accountv})}// 密码行用 InputType.Password 隐藏明文Row(){Text(密码).width(60)TextInput({placeholder:请输入密码}).layoutWeight(1).type(InputType.Password).onChange((v){this.passwordv})}Button(登录).width(100%).backgroundColor(#007DFF).onClick((){// 真实项目里这里换成你的登录请求console.info(账号this.account 密码this.password)})}.width(100%).height(100%).padding(20)}}你会看到什么一个竖排登录页。顶部粗体标题中间两行「标签 输入框」底部一根占满宽度的蓝色登录按钮。在输入框打字、点登录DevEco 的 Log 面板会打印你输入的内容。动手改一改建议先试这个把Column({ space: 16 })改成space: 32重新运行感受元素间距被拉大。给密码行的TextInput删掉.type(InputType.Password)再输入一次看明文效果。把Button(登录)改成Button(注册)按钮文字立刻变——这就是声明式改描述即改界面。写在最后Column 和 Row 是 ArkUI 的全部地基。你今天只要把嵌套 space 对齐这三板斧练熟大部分静态布局都能搞定。下一篇我讲 Flex 弹性布局专门对付那些一行塞不下要换行的场景。动手敲一遍上面的代码跑起来看看效果——别偷懒真的敲过一遍比看十遍都管用。