ArkUI Grid 组件详解与使用指南
Grid 是 ArkUI 中用于实现网格布局的容器组件,能够以行和列的形式排列子组件。以下是 Grid 组件的详细介绍和使用方法。
基本介绍
Grid 组件特点:
- 支持固定列数和自适应布局
- 提供灵活的间距和排列控制
- 支持滚动显示大量项目
- 可以实现复杂的网格布局效果
基本使用
1. 简单网格布局
@Entry
@Component
struct SimpleGridExample {private data: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6']build() {Grid() {ForEach(this.data, (item: string) => {GridItem() {Text(item).fontSize(16).textAlign(TextAlign.Center).width('100%').height('100%').backgroundColor('#f0f0f0')}}, (item: string) => item)}.columnsTemplate('1fr 1fr 1fr') // 3等分列.rowsTemplate('1fr 1fr') // 2等分行.columnsGap(10) // 列间距.rowsGap(10) // 行间距.height(300).width('100%').margin(10)}
}
2. 自适应网格
@Entry
@Component
struct AutoGridExample {private data: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']build() {Grid() {ForEach(this.data, (item: string) => {GridItem() {Text(item).fontSize(20).fontWeight(FontWeight.Bold).textAlign(TextAlign.Center).width('100%').height('100%').backgroundColor('#e6f7ff').borderRadius(8)}}, (item: string) => item)}.maxCount(4) // 每行最多4项.minCount(2) // 每行至少2项.cellLength(100) // 每个网格项的长度.height('100%').width('100%').padding(10)}
}
核心功能
1. 网格模板布局
Grid() {// GridItems...
}
.columnsTemplate('100px 1fr 2fr') // 第一列固定100px,第二列1份,第三列2份
.rowsTemplate('50px 1fr 50px') // 第一行和第三行固定50px,中间行自适应
2. 网格间距控制
Grid() {// GridItems...
}
.columnsGap(12) // 列间距12px
.rowsGap(8) // 行间距8px
3. 滚动网格
Grid() {ForEach(Array(20).fill(0).map((_, index) => {GridItem() {Text(`Item ${index + 1}`)// 样式...}})
}
.columnsTemplate('1fr 1fr 1fr')
.height(400) // 固定高度实现滚动
.width('100%')
.scrollBar(BarState.On) // 显示滚动条
4. 响应式网格
@Entry
@Component
struct ResponsiveGridExample {@State gridColumns: string = '1fr 1fr' // 默认2列build() {Column() {// 切换列数按钮Row() {Button('2列').onClick(() => { this.gridColumns = '1fr 1fr' })Button('3列').onClick(() => { this.gridColumns = '1fr 1fr 1fr' })Button('4列').onClick(() => { this.gridColumns = '1fr 1fr 1fr 1fr' })}.margin(10)// 响应式网格Grid() {ForEach(Array(12).fill(0).map((_, index) => {GridItem() {Text(`Item ${index + 1}`)// 样式...}})}.columnsTemplate(this.gridColumns).rowsGap(10).columnsGap(10).height('80%').width('100%')}}
}
高级功能
1. 不规则网格项
Grid() {// 跨2列的项GridItem({ columnStart: 0, columnEnd: 2 }) {Text('跨两列')// 样式...}// 跨2行的项GridItem({ rowStart: 1, rowEnd: 3 }) {Text('跨两行')// 样式...}// 普通项GridItem() {Text('普通项')// 样式...}
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('100px 100px 100px')
2. 网格项动画
@State scaleValue: number = 1build() {Grid() {GridItem() {Text('点击放大').width('100%').height('100%').onClick(() => {animateTo({duration: 300,curve: Curve.EaseInOut}, () => {this.scaleValue = this.scaleValue === 1 ? 1.2 : 1})}).scale({ x: this.scaleValue, y: this.scaleValue })}// 更多GridItems...}// 网格配置...
}
3. 网格拖拽排序
@Entry
@Component
struct DraggableGridExample {@State items: string[] = ['A', 'B', 'C', 'D', 'E', 'F']@State draggedIndex: number = -1build() {Grid() {ForEach(this.items, (item: string, index: number) => {GridItem() {Text(item).width('100%').height('100%').gesture(PanGesture({ distance: 5 }).onActionStart(() => {this.draggedIndex = index}).onActionUpdate((event: GestureEvent) => {// 处理拖拽逻辑}).onActionEnd(() => {this.draggedIndex = -1}))}.zIndex(this.draggedIndex === index ? 1 : 0)}, (item: string) => item)}.columnsTemplate('1fr 1fr 1fr').height(400).width('100%')}
}
性能优化
1. 复用网格项
Grid() {LazyForEach(this.dataSource, (item: ItemData) => {GridItem() {// 内容...}}, (item: ItemData) => item.id.toString())
}
2. 固定尺寸网格项
Grid() {ForEach(this.data, (item) => {GridItem() {// 内容...}.width(100) // 固定宽度.height(120) // 固定高度})
}
3. 虚拟滚动
Grid() {// 大数据集使用虚拟滚动Virtualize({ scroller: this.scroller,builder: (index: number) => {return this.buildGridItem(index)},count: this.data.length})
}
.height(500)
.width('100%')
最佳实践
-
合理设计网格结构:
- 根据内容类型选择合适的列数和行高
- 考虑不同屏幕尺寸的适配
-
优化性能:
- 大数据集使用懒加载或虚拟滚动
- 避免过度复杂的网格项嵌套
-
增强用户体验:
- 为网格项添加适当的交互反馈
- 实现平滑的滚动和动画效果
-
响应式设计:
- 根据屏幕宽度动态调整列数
- 使用相对单位确保布局弹性
实际应用示例
1. 图片网格画廊
@Entry
@Component
struct ImageGridGallery {private images = [{ id: 1, url: $r('app.media.image1') },{ id: 2, url: $r('app.media.image2') },// 更多图片...]build() {Grid() {ForEach(this.images, (image) => {GridItem() {Image(image.url).width('100%').height('100%').objectFit(ImageFit.Cover).onClick(() => {// 处理图片点击})}.aspectRatio(1) // 保持正方形}, (image) => image.id.toString())}.columnsTemplate('1fr 1fr 1fr').columnsGap(5).rowsGap(5).width('100%').padding(10)}
}
2. 仪表盘布局
@Entry
@Component
struct DashboardLayout {build() {Grid() {// 顶部指标卡 - 跨3列GridItem({ columnStart: 0, columnEnd: 3 }) {DashboardCard('总体数据', '1000')}// 左侧图表 - 跨2行GridItem({ rowStart: 1, rowEnd: 3 }) {DashboardCard('趋势分析', '图表')}// 右侧小指标GridItem({ columnStart: 1 }) {DashboardCard('今日新增', '120')}GridItem({ columnStart: 2 }) {DashboardCard('完成率', '85%')}GridItem({ columnStart: 1, columnEnd: 3 }) {DashboardCard('最近活动', '详情')}}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('80px 1fr 1fr').columnsGap(10).rowsGap(10).height('100%').width('100%').padding(10)}@BuilderDashboardCard(title: string, value: string) {Column() {Text(title).fontSize(14).fontColor('#666')Text(value).fontSize(24).fontWeight(FontWeight.Bold).margin({ top: 8 })}.width('100%').height('100%').padding(10).backgroundColor('#fff').borderRadius(8).shadow({ radius: 4, color: '#00000020', offsetX: 1, offsetY: 1 })}
}
通过合理使用 Grid 组件,可以创建出灵活、高效的网格布局,适用于各种应用场景,如图库、仪表盘、产品列表等。