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

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

文章目录

    • 前言
    • 先搞懂一件事:什么是"声明式"
      • 代码实现
    • Column:竖着排,从上到下
      • 核心代码
    • Row:横着排,从左到右
      • 完整示例
    • 重点来了:嵌套组合
      • 代码解析
    • 小白问答
    • 常见误区(小白必踩)
    • 完整可运行示例:写一个登录页
      • 实现拆解
    • 写在最后

前言

我刚转到 HarmonyOS 那会儿,最不习惯的就是它的 UI 写法。以前写界面是一行一行"命令"系统"把这个按钮放到那里",到了 ArkUI 这边,你改成"描述"界面长什么样——剩下的交给框架去算。

这篇文章我就用最朴素的大白话,把ColumnRow这两个最基础、也最常用的布局容器讲透。读完你就能自己摆出 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:横着排,从左到右

RowColumn是一对,区别只是方向: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 把中间空间吃满,箭头自然贴右。

小白问答

Q:Column 和 Row 能不能无限嵌套?
能,但别超过 4 层,不然你自己都看不懂,性能也亏。

Q:space 和 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 行内组合 + 状态绑定@Entry@Componentstruct LoginPage{@Stateaccount:string=''// 账号,@State 让输入能驱动 UI@Statepassword:string=''// 密码build(){Column({space:16}){// 整页竖向,子元素间距 16vpText('欢迎登录').fontSize(24).fontWeight(FontWeight.Bold)// 账号行:固定宽标签 + 输入框Row(){Text('账号').width(60)TextInput({placeholder:'请输入手机号'}).layoutWeight(1)// 输入框吃掉剩余宽度.onChange((v)=>{this.account=v})}// 密码行:用 InputType.Password 隐藏明文Row(){Text('密码').width(60)TextInput({placeholder:'请输入密码'}).layoutWeight(1).type(InputType.Password).onChange((v)=>{this.password=v})}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 弹性布局,专门对付那些"一行塞不下要换行"的场景。

动手敲一遍上面的代码,跑起来看看效果——别偷懒,真的,敲过一遍比看十遍都管用。

http://www.cnnetsun.cn/news/3311400.html

相关文章:

  • 蓝牙 Mesh vs. 经典蓝牙:智能家居组网 5 大关键指标对比
  • Flappy Bird游戏开发终极资源包:5分钟快速上手指南
  • Seedance 2.0多模态AI视频生成:从提示词工程到批量生产工作流
  • PUBG罗技鼠标宏终极指南:5分钟掌握专业压枪技巧
  • ADS122U04与PIC18F86J15构建高精度工业测量系统
  • AI Agent开发实战:从零掌握核心架构与7天速成指南
  • 2026年AI聚合平台深度对比:六家服务商的Token计量、协议兼容与生产级表现选型指南
  • Wand-Enhancer:彻底解除Wand时间限制,免费享受专业版功能的终极方案
  • 指令系统设计实战:3种操作数指令与扩展操作码的12位地址空间计算
  • ComfyUI-VideoHelperSuite:解决AI视频工作流核心问题的完整方案
  • BEVFormer算子落地难点:从PyTorch到车规芯片的语义鸿沟与访存优化
  • 人形机器人2026量产元年:从供应链确定性看制造落地
  • 工业负载控制:TPD2015FN与TM4C1294方案解析
  • 基于TPS61170与PIC18LF4680的高效DC-DC升压转换方案
  • 如何快速配置罗技鼠标宏:PUBG压枪脚本的5分钟终极指南
  • Jetson Orin部署BEVFormer:JetPack 6.2+TensorRT 10.3实战指南
  • NBTExplorer终极指南:5步掌握Minecraft数据编辑的艺术 [特殊字符]
  • 3分钟解锁Godot游戏资源:专业PCK解包工具完全指南
  • AI智能体手机技术解析:端侧大模型与工具调用的工程实践
  • 程序员为什么不自己开发一个小程序赚钱?
  • Meta:FADE自适应优势函数优化RL
  • C++代码优化五大实战策略:DeepSeek R1辅助下的性能提升指南
  • GetQzonehistory:一键找回被遗忘的QQ空间记忆,你的数字青春档案馆
  • 最大熵原理:用最少假设构建最鲁棒贝叶斯先验
  • Flink 1.20 LTS 与 Spark 3.5 流处理对比:3个核心场景下的吞吐与延迟实测
  • 工业级遗传算法实战:从编码策略到动态约束处理
  • Cesium 曲线管道教程
  • Equalizer APO:免费开源的系统级音频均衡器,让你的电脑音质瞬间升级!
  • ADS131M02与PIC18F47K40的高精度数据采集方案
  • C++头文件循环包含:原理剖析与工程化解决方案