鸿蒙开发3--UI布局(玩转鸿蒙的Row、Column与Stack容器)

在前两文中,我们已经掌握了怎么使用基础组件并通过@State来驱动UI更新。

但是,要从简单的按钮和文本进化到精美的用户界面,我们必须学会怎么组织和排列这些组件。

今天,我们聊一聊ArkUI中最核心的布局容器:Row、Column、Stack,以及强大的Flex弹性布局。

一、布局的本质

在ArkUI中,布局就是把一组UI组件(子组件)按照特定的规则放在一个容器(父组件)里。

选择哪种容器,就决定了他内部组件的排列方式。

可以想象成整理书架,你可以选择横着放、竖着放,或者把几本书叠在一起。

1.1. Column (垂直布局)

Column是我们最熟悉的布局容器之一,他会把所有的子组件从上到下垂直排列。

基础用法:

TypeScript 复制代码
 Column() {
   Text('用户登录').fontSize(24).fontWeight(FontWeight.Bold)
   TextInput({ placeholder: '请输入用户名' }).margin(10)
   TextInput({ placeholder: '请输入密码' }).margin(10)
   Button('登录').width(200).margin(10)
 }
 .width('100%')
 .padding(20)

这个简单的登录表单就是Column的典型应用场景。

常用属性 (对齐方式): Column内部的对齐是控制水平方向(交叉轴)的位置。

  • alignItems(HorizontalAlign):

    • HorizontalAlign.Start: 水平居左(默认)。

    • HorizontalAlign.Center: 水平居中。

    • HorizontalAlign.End: 水平居右。

TypeScript 复制代码
 Column() {
   // ...子组件
 }
 .width('100%')
 .alignItems(HorizontalAlign.Center) // 让所有子组件水平居中

1.2. Row (水平布局)

跟Column相反,Row会把所有子组件从左到右水平排列。

基础用法:

TypeScript 复制代码
Row() {
   Image($r('app.media.avatar'))
     .width(60)
     .height(60)
     .borderRadius(30)
 ​
   Column() {
     Text('用户名').fontSize(18)
     Text('个性签名').fontSize(14).fontColor(Color.Gray)
   }
   .alignItems(HorizontalAlign.Start)
   .margin({ left: 10 })
 }
 .padding(15)
 .backgroundColor(Color.White)
 .borderRadius(10)

这种左边头像、右边用户信息的结构,就比较适合用Row。

常用属性 (对齐方式): Row内部的对齐是控制垂直方向(交叉轴)的位置。

  • alignItems(VerticalAlign):

    • VerticalAlign.Top: 垂直居上。

    • VerticalAlign.Center: 垂直居中(默认)。

    • VerticalAlign.Bottom: 垂直居下。

1.3. Stack (层叠布局)

Stack的布局允许子组件像Photoshop的图层一样,一个接一个的在Z轴上堆叠起来。

后添加的组件会覆盖在先添加的组件之上。

基础用法:

TypeScript 复制代码
 Stack() {
   // 第一层:背景图
   Image($r('app.media.card_background'))
     .width('100%')
     .height(200)
 ​
   // 第二层:叠加在图片上的文字
   Text('新用户专属优惠券')
     .fontColor(Color.White)
     .fontSize(22)
 }
 .width(350)
 .borderRadius(15)

在背景图上叠加文字、在视频上放置播放按钮等场景,最适合的就是Stack。

常用属性 (对齐方式): Stack的对齐同时控制水平和垂直方向。

  • alignContent(Alignment): 使用Alignment枚举值,可以精确定位子组件在9个方向的位置(如TopStart, Center, BottomEnd等)。默认是Alignment.Center。

1.4. Flex (弹性布局)

Flex是目前最强大、最灵活的布局方式,Row和Column实际上是Flex的特例。

他不仅能控制主轴方向(水平或垂直),还能管理空间分配、自动换行等复杂场景。

  • Flex({ direction: FlexDirection.Row }) 等价于Row。

  • Flex({ direction: FlexDirection.Column }) 等价于Column。

Flex的核心属性:

  • direction: 主轴方向 (Row, Column, RowReverse, ColumnReverse)。

  • justifyContent: 主轴上的对齐方式 (Start, Center, End, SpaceBetween, SpaceAround, SpaceEvenly)。

  • alignItems: 交叉轴上的对齐方式 (Start, Center, End, Stretch)。

  • wrap: 是否自动换行 (FlexWrap.Wrap, FlexWrap.NoWrap)。

当Row和Column的简单对齐无法满足需求时,比如需要实现两端对齐(SpaceBetween),就必须使用Flex。

二、搭建一个简单的个人名片

根据上面的布局暂时是,构建一个如下图所示的个人名片。

3.1准备

示例图中一共需要四张图片:

头像图标:avatar_icon.png

电话图标:phone_icon.png

邮箱图标:email_icon.png

地址图标:location_icon.png

这些png图片可以去https://www.iconfinder.com/下载。

2.2分析布局

最外层:整个名片是一个从上到下的结构,用Column。

顶部区域:头像、姓名、职位是水平排列的,用Row。

在Row内部,姓名和职位又是垂直排列的,所以需要一个嵌套的Column。

中间区域:分割线,一个简单的Divider组件。

底部区域:三个带图标的联系方式,是水平均匀分布的,用Flex布局最合适。

2.3创建模块

我们还是跟之前的计数器模块一样创建一个独立的模块。

上一步准备的图片资源放在新建模块resources/base/media目录下。

2.4代码实现

TypeScript 复制代码
 @Entry
 @Component
 struct Index {
   build() {
     // 1. 最外层:垂直布局
     Column() {
       // 2. 顶部区域:水平布局
       Row() {
         Image($r('app.media.avatar'))
           .width(80)
           .height(80)
           .borderRadius(40)
 ​
         // 姓名和职位的垂直容器
         Column() {
           Text('懒惰蜗牛')
             .fontSize(22)
             .fontWeight(FontWeight.Bold)
           Text('鸿蒙应用开发工程师')
             .fontSize(16)
             .fontColor(Color.Gray)
             .margin({ top: 5 })
         }
         .alignItems(HorizontalAlign.Start) // 文字左对齐
         .margin({ left: 15 })
       }
       .width('100%')
       .padding(20)
 ​
       // 3. 分割线
       Divider().strokeWidth(1).color('#f1f1f1').margin({ top: 10 })
 ​
       // 4. 底部联系方式:弹性布局实现均匀分布
       Flex({ justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
         // 电话
         Column() {
           Image($r('app.media.phone_icon')).width(24).height(24)
           Text('电话').fontSize(14).margin({ top: 5 })
         }
         // 邮箱
         Column() {
           Image($r('app.media.email_icon')).width(24).height(24)
           Text('邮箱').fontSize(14).margin({ top: 5 })
         }
         // 地址
         Column() {
           Image($r('app.media.location_icon')).width(24).height(24)
           Text('地址').fontSize(14).margin({ top: 5 })
         }
       }
       .width('100%')
       .height(100)
 ​
     }
     .width(350)
     .backgroundColor(Color.White)
     .borderRadius(15)
     .shadow({ radius: 10, color: '#dddddd' })
     .padding(10)
   }
 }

总结

今天,我们学习了ArkUI布局的四大金刚:

  • Column:垂直线性布局。

  • Row:水平线性布局。

  • Stack:层叠覆盖布局。

  • Flex:功能最全的弹性布局。

通过组合这些容器,我们可以构建出任何复杂的静态页面。尝试修改布局属性,观察UI的变化,可以加深对布局系统的理解。

相关推荐
我命由我123454 小时前
Photoshop - Photoshop 工具库
笔记·学习·ui·职场和发展·职场·photoshop·ps
兰亭妙微8 小时前
兰亭妙微桌面端界面设计优化方案:避免QT开发中的“老旧感”
开发语言·qt·ui·用户体验设计公司·ui设计公司
_waylau8 小时前
如何将鸿蒙5应用升级到鸿蒙6
华为·harmonyos·鸿蒙·鸿蒙系统
爱笑的眼睛118 小时前
HarmonyOS应用开发深度解析:ArkTS语法与组件化开发实践
华为·harmonyos
我命由我1234511 小时前
Photoshop - Photoshop 工具栏(1)移动工具
笔记·学习·ui·职场和发展·求职招聘·职场发展·photoshop
安卓开发者12 小时前
鸿蒙NEXT Wi-Fi扫描开发指南:从基础到实战
华为·harmonyos
安卓开发者13 小时前
在鸿蒙NEXT中发起HTTP网络请求:从入门到精通
网络·http·harmonyos
米羊12115 小时前
【鸿蒙心迹】工匠雕琢,攻克难题(下)
华为·harmonyos
我命由我1234519 小时前
Photoshop - Photoshop 工具从工具栏消失
笔记·学习·ui·职场和发展·职场发展·photoshop·ps