ArkUI 布局优化:嵌套少一层,页面顺一截
【摘要】 今天我们不做性能压测,只把几种常见布局写法摆在一起看:什么时候该少套一层,什么时候该抽一个 Builder。 初学 ArkUI 时,很容易一看到对齐问题就继续套 Row、Column。这样能写出来,但代码读起来会越来越绕。我们先看一个过度嵌套的小块,再看一个更扁平的写法。 第一块故意写得偏绕。只是标题、描述和一点说明,
ArkUI 布局优化:嵌套少一层,页面顺一截
今天我们不做性能压测,只把几种常见布局写法摆在一起看:什么时候该少套一层,什么时候该抽一个 Builder。
初学 ArkUI 时,很容易一看到对齐问题就继续套 Row、Column。这样能写出来,但代码读起来会越来越绕。我们先看一个过度嵌套的小块,再看一个更扁平的写法。
第一块故意写得偏绕。只是标题、描述和一点说明,却套了好几层。它不是不能用,而是维护时不够直观。
第二块把内容压回一层 Row。左侧 Column 用 layoutWeight(1) 占剩余空间,右侧放按钮。这个结构更像我们真正想表达的 UI:一段主要信息,加一个操作区。
第三块展示 Builder。重复出现的小行、信息块、标签组,都可以抽成 Builder。这样主体页面会更短,读代码时也更容易找到重点。
你现在项目里有没有那种“明明只是一个小卡片,却套了六七层”的布局?这种代码通常不是谁故意写复杂,而是一路修出来的。
完整代码
class OptimizationPoint {
title: string
desc: string
color: string
constructor(title: string, desc: string, color: string) {
this.title = title
this.desc = desc
this.color = color
}
}
@Entry
@Component
struct ArkUILayoutOptimizationDemo {
private points: OptimizationPoint[] = [
new OptimizationPoint('少套容器', '只是为了留白或对齐时,先看看现有组件属性够不够。', '#2563EB'),
new OptimizationPoint('扁平分组', '同一层级的内容尽量放在同一个布局里,阅读代码更快。', '#0F766E'),
new OptimizationPoint('抽出 Builder', '重复小块可以抽成 Builder,结构会更稳。', '#C2410C')
]
@Builder
sectionTitle(title: string, desc: string) {
Column({ space: 6 }) {
Text(title)
.fontSize(19)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(desc)
.fontSize(13)
.fontColor('#6B7280')
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
nestedCard() {
Column({ space: 8 }) {
Row() {
Column() {
Row() {
Column({ space: 4 }) {
Text('过度嵌套')
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor('#B91C1C')
Text('Column > Row > Column > Row')
.fontSize(12)
.fontColor('#6B7280')
}
.padding(10)
.backgroundColor('#FEF2F2')
.borderRadius(8)
}
.width('100%')
}
.width('100%')
}
.width('100%')
Text('如果只是为了标题、描述、按钮排在一起,这么套会让后续维护很累。')
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(20)
}
.width('100%')
.padding(14)
.borderRadius(12)
.backgroundColor('#FFF7ED')
.border({ width: 1, color: '#FED7AA' })
}
@Builder
flatCard() {
Row({ space: 12 }) {
Column({ space: 6 }) {
Text('更扁平')
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor('#047857')
Text('Row + layoutWeight 就能把主内容和操作区分开。')
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(20)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
Text('查看')
.fontSize(13)
.fontWeight(FontWeight.Medium)
.fontColor('#FFFFFF')
.height(36)
.padding({ left: 16, right: 16 })
.borderRadius(18)
.backgroundColor('#0F766E')
}
.width('100%')
.padding(14)
.borderRadius(12)
.backgroundColor('#ECFDF5')
.border({ width: 1, color: '#A7F3D0' })
}
@Builder
pointRow(item: OptimizationPoint) {
Row({ space: 12 }) {
Text(item.title.substring(0, 1))
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.textAlign(TextAlign.Center)
.width(38)
.height(38)
.borderRadius(19)
.backgroundColor(item.color)
Column({ space: 4 }) {
Text(item.title)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(item.desc)
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(20)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding(12)
.borderRadius(10)
.backgroundColor('#F8FAFC')
.border({ width: 1, color: '#E5E7EB' })
}
build() {
Scroll() {
Column({ space: 22 }) {
Column({ space: 8 }) {
Text('ArkUI 布局优化')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('嵌套少一层,页面顺一截')
.fontSize(16)
.fontColor('#4B5563')
Text('这一篇不做性能压测,只把常见的布局写法放在一起看:什么时候该少套一层,什么时候该抽成小块。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
this.sectionTitle('对比一:只是排列内容,别套太深', '嵌套不是错,但每多一层都应该有明确理由。')
this.nestedCard()
this.flatCard()
this.sectionTitle('对比二:重复结构交给 Builder', '列表里的小行、信息块、标签组,抽出来之后主体会清爽很多。')
Column({ space: 10 }) {
ForEach(this.points, (item: OptimizationPoint) => {
this.pointRow(item)
}, (item: OptimizationPoint) => item.title)
}
.width('100%')
this.sectionTitle('对比三:优先用组件自己的布局属性', '比如 space、padding、layoutWeight、alignItems,很多时候已经能解决排列问题。')
Column({ space: 10 }) {
Row({ space: 8 }) {
Text('space')
.fontSize(13)
.fontColor('#1D4ED8')
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.borderRadius(16)
.backgroundColor('#DBEAFE')
Text('padding')
.fontSize(13)
.fontColor('#0F766E')
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.borderRadius(16)
.backgroundColor('#CCFBF1')
Text('alignItems')
.fontSize(13)
.fontColor('#C2410C')
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.borderRadius(16)
.backgroundColor('#FFEDD5')
}
.width('100%')
Text('先把这些基础属性用顺,很多页面不会一开始就走向复杂嵌套。')
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(20)
.width('100%')
.padding(12)
.borderRadius(10)
.backgroundColor('#F9FAFB')
}
.width('100%')
}
.width('100%')
.padding({ left: 18, right: 18, top: 22, bottom: 32 })
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)