ArkUI GridRow:响应式别靠猜屏幕宽度
【摘要】 今天我们用 GridRow 和 GridCol 搭一个十二列栅格页面,先把 span、offset、order 和 gutter 这些最常用的能力看明白。 准备很简单:页面里只用 ArkUI 自带组件,不需要额外资源。我们把整行交给 GridRow,再让每个 GridCol 说明自己占几列。这样写比手算百分比舒服,也更
ArkUI GridRow:响应式别靠猜屏幕宽度
今天我们用 GridRow 和 GridCol 搭一个十二列栅格页面,先把 span、offset、order 和 gutter 这些最常用的能力看明白。
准备很简单:页面里只用 ArkUI 自带组件,不需要额外资源。我们把整行交给 GridRow,再让每个 GridCol 说明自己占几列。这样写比手算百分比舒服,也更容易改。
第一块先看 span。columns: 12 表示一行分成十二份,span: 4 就是占四份,所以一行正好放三块。这里的重点不是数字多神奇,而是我们终于不用在 width('33%') 这种写法里来回试。
第二块看 offset。它会在当前列前面空出几列,适合做错位和居中。如果只是想让某块内容往右挪,不用再塞一个空白组件。
第三块看 order。它让显示顺序和代码顺序分开。一般来说别滥用,但遇到少量展示顺序调整时,它比大段挪代码更干净。
最后再把 gutter 和 alignItems 放在一起看。gutter 统一处理格子间距,alignItems 处理同一行里不同高度内容的交叉轴对齐。你写卡片入口、数据面板、设置页分区时,大概率会反复用到这几个点。
你平时写响应式布局时,是更喜欢十二列栅格,还是直接用 Row/Column 一路排下去?这个问题没有标准答案,但不同项目里取舍会很不一样。
完整代码
class GridRowFeature {
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 ArkUIGridRowDemo {
private features: GridRowFeature[] = [
new GridRowFeature('span 4', '一行三列,适合入口区', '#2563EB'),
new GridRowFeature('span 6', '一行两列,信息更舒展', '#0F766E'),
new GridRowFeature('span 12', '独占整行,适合重点内容', '#C2410C'),
new GridRowFeature('offset', '留出起始空位,少套一层容器', '#7C3AED'),
new GridRowFeature('order', '显示顺序可以和代码顺序分开', '#B45309'),
new GridRowFeature('gutter', '列和行之间统一留白', '#1D4ED8')
]
@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
featureCard(item: GridRowFeature) {
Column({ space: 8 }) {
Text(item.title)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor(item.color)
Text(item.desc)
.fontSize(12)
.fontColor('#4B5563')
.lineHeight(18)
}
.width('100%')
.height(92)
.padding(12)
.borderRadius(8)
.backgroundColor('#F8FAFC')
.border({ width: 1, color: '#E5E7EB' })
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)
}
@Builder
orderTile(text: string, color: string) {
Text(text)
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor('#FFFFFF')
.textAlign(TextAlign.Center)
.width('100%')
.height(56)
.borderRadius(8)
.backgroundColor(color)
}
build() {
Scroll() {
Column({ space: 22 }) {
Column({ space: 8 }) {
Text('ArkUI GridRow')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('响应式别靠猜屏幕宽度')
.fontSize(16)
.fontColor('#4B5563')
Text('GridRow 把一行切成固定列数,GridCol 决定每块占几列。我们先用十二列栅格看清 span、offset、order 和 gutter 的位置。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
this.sectionTitle('span:先决定每块占几列', 'columns 给整行定格数,span 给每个 GridCol 定宽度。')
GridRow({ columns: 12, gutter: { x: 8, y: 8 } }) {
GridCol({ span: 4 }) {
this.featureCard(this.features[0])
}
GridCol({ span: 4 }) {
this.featureCard(this.features[1])
}
GridCol({ span: 4 }) {
this.featureCard(this.features[2])
}
}
.width('100%')
this.sectionTitle('offset:需要错位时,不用再塞空白 View', 'offset 会在当前列前面留出列宽,适合做居中卡片或局部错位。')
GridRow({ columns: 12, gutter: { x: 8, y: 8 } }) {
GridCol({ span: 6 }) {
this.featureCard(new GridRowFeature('左侧 span 6', '先占掉半行', '#0F766E'))
}
GridCol({ span: 3, offset: 3 }) {
this.featureCard(new GridRowFeature('offset 3', '前面空三列', '#7C3AED'))
}
GridCol({ span: 4, offset: 4 }) {
this.featureCard(new GridRowFeature('居中感', '四列空位加四列内容', '#C2410C'))
}
}
.width('100%')
this.sectionTitle('order:代码顺序和显示顺序可以分开', '少量调整显示位置时,order 比挪动整段代码更直接。')
GridRow({ columns: 12, gutter: { x: 8, y: 8 } }) {
GridCol({ span: 4, order: 3 }) {
this.orderTile('代码第 1 个 / order 3', '#1D4ED8')
}
GridCol({ span: 4, order: 1 }) {
this.orderTile('代码第 2 个 / order 1', '#0F766E')
}
GridCol({ span: 4, order: 2 }) {
this.orderTile('代码第 3 个 / order 2', '#C2410C')
}
}
.width('100%')
.alignItems(ItemAlign.Center)
this.sectionTitle('gutter + alignItems:间距和交叉轴一起管', 'gutter 统一处理格子间距,alignItems 处理这一行里不同高度内容的对齐。')
GridRow({ columns: 12, gutter: { x: 10, y: 10 } }) {
GridCol({ span: 4 }) {
Text('短卡片')
.fontSize(14)
.fontColor('#111827')
.width('100%')
.height(52)
.borderRadius(8)
.backgroundColor('#DBEAFE')
.textAlign(TextAlign.Center)
}
GridCol({ span: 4 }) {
Text('高一点的卡片')
.fontSize(14)
.fontColor('#111827')
.width('100%')
.height(86)
.borderRadius(8)
.backgroundColor('#CCFBF1')
.textAlign(TextAlign.Center)
}
GridCol({ span: 4 }) {
Text('普通卡片')
.fontSize(14)
.fontColor('#111827')
.width('100%')
.height(68)
.borderRadius(8)
.backgroundColor('#FED7AA')
.textAlign(TextAlign.Center)
}
}
.width('100%')
.alignItems(ItemAlign.Center)
}
.width('100%')
.padding({ left: 18, right: 18, top: 22, bottom: 32 })
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)