从 Row 到 WaterFlow:鸿蒙应用开发ArkUI布局全家桶教程
默认 0 表示不隐藏。
·
一、线性布局(Row / Column)
| 方向 | 语法糖 | 适用 |
|---|---|---|
| 水平 | Row |
工具栏、按钮组 |
| 垂直 | Column |
表单、列表项 |
Column({ space: 8 }) {
Text('用户名').fontSize(16)
TextInput().placeholder('请输入')
Button('登录')
}.width('100%').padding(16)
关键属性速记justifyContent → 主轴对齐alignItems → 交叉轴对齐space → 相邻子组件间距
二、弹性布局(Flex)
一句话:Flex = Row + Column + wrap + layoutWeight
Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
ForEach([1,2,3,4,5], () => {
Text('标签').layoutWeight(1).margin(4)
})
}
| 场景 | 推荐值 |
|---|---|
| 等分 | layoutWeight(1) |
| 拉齐尾部 | justifyContent: FlexAlign.SpaceBetween |
| 换行 | wrap: FlexWrap.Wrap |
三、层叠布局(Stack)
Stack({ alignContent: Alignment.BottomEnd }) {
Image($r('app.media.bg'))
FloatingActionButton() // 悬浮按钮
.margin(16)
}
zIndex 越大越靠上;支持 hitTestBehavior 控制事件穿透。
四、相对布局(RelativeContainer)
通过 9 个锚点(上/下/左/右/居中)精准定位:
RelativeContainer() {
Text('A').id('A')
.alignRules({
top: { anchor: '__container__', align: VerticalAlign.Top },
left: { anchor: '__container__', align: HorizontalAlign.Start }
})
Text('B').id('B')
.alignRules({
left: { anchor: 'A', align: HorizontalAlign.End },
centerVertical: { anchor: 'A' }
})
}
五、栅格布局(GridRow / GridCol)
12 栅格系统,断点自动切换:
GridRow({ gutter: 12 }) {
ForEach(this.newsList, item =>
GridCol({ span: { sm: 12, md: 6, lg: 4 } }) {
NewsCard({ item })
}
)
}
| 断点 | 典型宽度 | 列数 |
|---|---|---|
| sm | <520 vp | 12 |
| md | 520-840 | 12 |
| lg | >840 | 12 |
span取值 1-12,必须 父容器设置columns: 12(默认即 12)。
六、网格布局(Grid)
适用于 固定行列 的棋盘、相册、九宫格:
Grid() {
ForEach(this.imgList, img =>
GridItem() {
Image(img).objectFit(ImageFit.Cover)
}
)
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(8)
.rowsGap(8)
七、瀑布流布局(WaterFlow)
子项高度可变,自动填满空白;
WaterFlow() {
LazyForEach(this.dataSource, item =>
FlowItem() {
ProductCard({ item })
}
)
}
.columnsGap(12)
.rowsGap(12)
.columnsTemplate('1fr 1fr') // 两列
八、列表布局(List)
长列表首选,支持懒加载 + 滑动事件:
List({ lanes: { sm: 1, md: 2, lg: 3 } }) {
LazyForEach(this.dataSource, item =>
ListItem() {
ArticleRow({ item })
}
)
}
.onScrollIndex(start => console.log('开始索引:' + start))
九、轮播布局(Swiper)
Swiper() {
ForEach(this.banners, banner =>
Image(banner.url).borderRadius(12)
)
}
.autoPlay(true)
.interval(3000)
.indicator(true)
.displayCount({ sm: 1, md: 2, lg: 3 }) // 响应式
十、页签布局(Tabs)
底部、顶部、侧边一键切换:
Tabs({ barPosition: BarPosition.End }) {
TabContent() { HomePage() }.tabBar('首页')
TabContent() { ProfilePage() }.tabBar('我的')
}
.vertical(false) // true=侧边
.scrollable(true) // 支持手势滑动
十一、抽屉布局(SideBarContainer)
官方抽屉,零代码手势:
SideBarContainer(SideBarContainerType.Embed) {
Column() { /* 抽屉内容 */ }.width(240)
}
.controlButton({
top: 24,
left: 24,
icons: {
shown: $r('app.media.menu'),
hidden: $r('app.media.close')
}
})
十二、导航布局(Navigation)
单/双/三分栏一站式导航,自动适配折叠屏:
Navigation() {
NavRouter() {
Text('一级')
NavDestination() { DetailPage() }
}
}
.mode(NavigationMode.Auto) // Auto=根据宽度自动分栏
十三、原子布局(DisplayPriority & PriorityLayout)
空间不足时按优先级隐藏:
Row() {
Text('必须').displayPriority(2)
Text('可隐藏').displayPriority(1)
}
优先级 越大 越先被隐藏;默认 0 表示不隐藏。
十四、响应式布局 2×2 简化断点
| 状态 | 阈值 | 目录名 |
|---|---|---|
| 横向 Compact | <600 vp | hC |
| 横向 Regular | ≥600 vp | hR |
| 纵向 Compact | <800 vp | vC |
| 纵向 Regular | ≥800 vp | vR |
十五、常见错误 10 秒定位表
| 现象 | 根因 | 1 行解决 |
|---|---|---|
栅格 span 无效 |
父容器未 columns:12 |
GridRow({columns:12}) |
layoutWeight 无效 |
父容器无主轴尺寸 | 给 Row/Column 显式 width/height |
| 图片溢出 | 缺 objectFit |
.objectFit(ImageFit.Cover) |
| 断点监听无回调 | 缺 responsiveWindow |
module.json5 里开启 |
| 通知不显示 | 缺权限 | 动态申请 ohos.permission.NOTIFICATION |
更多推荐

所有评论(0)