#跟着若城学鸿蒙# 详解 Grid 布局容器(Grid & GridItem)
·
在复杂的内容展示场景中,网格布局能让我们以行列的方式整齐排列元素。ArkUI 提供了 Grid
容器及其子项组件 GridItem
,二者配合使用即可实现灵活的网格布局。本篇将从定义、属性、事件到完整示例,系统地介绍如何使用 Grid
和 GridItem
。
1. Grid 定义介绍
interface GridInterface {
(scroller?: Scroller): GridAttribute;
}
- scroller(可选):绑定一个
Scroller
控制器,以实现网格内容的可编程滚动。
一个
Grid
容器仅能包含GridItem
作为子组件,其它类型组件会被忽略。
1.1 基本示例
@Entry @Component struct GridDemo {
private data: string[] = ["1","2","3","4","5","6","7","8","9","10"];
build() {
Column({ space: 10 }) {
Grid() {
ForEach(data, (item) => {
GridItem() {
Text("Item " + item)
.fontSize(18)
.backgroundColor("#aabbcc")
.width("100%")
.height(70);
}
})
}
.columnsTemplate("1fr 1fr 1fr") // 均分为 3 列
.columnsGap(10) // 列间距 10vp
.rowsGap(10) // 行间距 10vp
.width("100%")
.height(170)
.backgroundColor(Color.Pink)
}
.padding(10)
.width("100%")
.height("100%");
}
}
@Entry @Component class GridDemo {
let data = Array(["1","2","3","4","5","6","7","8","9","10"])
func build() {
Column(10) {
Grid() {
ForEach(data, itemGeneratorFunc: { item, _ in
GridItem() {
Text("Item \(item)")
.fontSize(18)
.backgroundColor(0xaabbcc)
.width(100.percent)
.height(70)
}
})
}
.columnsTemplate("1fr 1fr 1fr")
.columnsGap(10)
.rowsGap(10)
.width(100.percent)
.height(170)
.backgroundColor(0xffc0cb)
}
.padding(10)
.width(100.percent)
.height(100.percent)
}
}
2. Grid 属性介绍
declare class GridAttribute<T> extends CommonMethod<T> {
columnsTemplate(value: string): T;
rowsTemplate(value: string): T;
columnsGap(value: number | string | Resource): T;
rowsGap(value: number | string | Resource): T;
cachedCount(value: number): T;
}
属性 | 说明 |
---|---|
columnsTemplate |
定义列模板,如 "1fr 1fr 1fr" 表示 3 列均分;也可用不同比例 "1fr 2fr 1fr" 等 |
rowsTemplate |
定义行模板,语法同 columnsTemplate ,默认 1 行 |
columnsGap |
列间距 |
rowsGap |
行间距 |
cachedCount |
预缓存子项数量,用于性能优化 |
“fr” 单位代表网格可用空间份数,多个“fr”组合可实现不同比例的分栏布局。
3. Grid 事件介绍
declare class GridAttribute<T> extends CommonMethod<T> {
onScrollIndex(event: (firstVisibleIndex: number) => void): T;
}
- onScrollIndex:当可视区的起始子项下标变化时触发回调,适合实现“懒加载”或“滚动到底部自动加载”功能。
4. GridItem 定义与属性
interface GridItemInterface {
(): GridItemAttribute;
}
declare class GridItemAttribute<T> extends CommonMethod<T> {
rowStart(value: number): T;
rowEnd(value: number): T;
columnStart(value: number): T;
columnEnd(value: number): T;
forceRebuild(value: boolean): T;
}
属性 | 说明 |
---|---|
rowStart |
当前项在网格中开始的行号(从 0 开始) |
rowEnd |
当前项在网格中结束的行号(不包含该行) |
columnStart |
当前项在网格中开始的列号 |
columnEnd |
当前项在网格中结束的列号 |
forceRebuild |
是否在重新构建时强制重建此节点,适用于需要动态变更布局的场景 |
4.1 跨行跨列示例
@Entry @Component struct GridSpanDemo {
private data = Array.from({ length: 10 }, (_, i) => i);
build() {
Grid() {
ForEach(data, (item, idx) => {
GridItem() {
Text("Item " + idx).fontSize(18).width("100%").height("100%")
}
// 第 2 个项(idx==1)跨两列
.columnStart(idx == 1 ? 0 : 0)
.columnEnd(idx == 1 ? 2 : 0)
// 第 5 个项(idx==4)跨两行
.rowStart(idx == 4 ? 0 : 0)
.rowEnd(idx == 4 ? 2 : 0)
})
}
.columnsTemplate("1fr 1fr 1fr")
.rowsTemplate("1fr 1fr 1fr")
.columnsGap(8)
.rowsGap(8)
.width("100%")
.height(300)
.backgroundColor(Color.LightGray)
}
}
5. 完整示例:动态配置网格
下面示例展示了如何根据屏幕宽度和设定的行列数,计算每个网格单元大小,并为特定项配置跨行跨列布局。
@Entry @Component struct GridFullDemo {
private screenWidth: number = px2vp(1080);
private colCount: number = 4;
private rowCount: number = 5;
private gap: number = 10;
private cellSize: number = (screenWidth - gap * (colCount + 1)) / colCount;
private items: number[] = Array.from({ length: 18 }, (_, i) => i);
build() {
Column() {
Grid() {
ForEach(items, (item, idx) => {
GridItem() {
Text("Item " + idx)
.fontSize(16)
.textAlign(TextAlign.Center)
.layoutWeight(1)
}
.width("100%")
.height("100%")
// 第 16 个跨两行
.rowStart(idx == 15 ? 0 : 0)
.rowEnd(idx == 15 ? 2 : 0)
// 第 17 个跨两列
.columnStart(idx == 16 ? 0 : 0)
.columnEnd(idx == 16 ? 2 : 0)
})
}
.columnsTemplate("1fr 1fr 1fr 1fr")
.rowsTemplate("1fr 1fr 1fr 1fr 1fr")
.columnsGap(gap)
.rowsGap(gap)
.padding({ left: gap, right: gap })
.width("100%")
.height(cellSize * rowCount + gap * (rowCount - 1))
}
.padding(10)
.width("100%")
.height("100%");
}
}
6. 小结
- Grid:通过
columnsTemplate
、rowsTemplate
灵活定义行列; - GridItem:可跨行跨列,将指定单元格占据更大空间;
- 支持行列间距 (
columnsGap
、rowsGap
) 与滚动绑定 (scroller
); - 结合
onScrollIndex
可实现懒加载等高级功能。
掌握了本篇内容,您即可在 ArkUI 中游刃有余地构建各种网格布局,满足不同屏幕和业务需求。
更多推荐
所有评论(0)