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 組件,可以創建出靈活、高效的網格布局,適用于各種應用場景,如圖庫、儀表盤、產品列表等。