首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >HarmonyOS应用开发实战 | ArkTS Grid网格组件使用指南

HarmonyOS应用开发实战 | ArkTS Grid网格组件使用指南

作者头像
红目香薰
发布2025-12-16 15:39:54
发布2025-12-16 15:39:54
2650
举报
文章被收录于专栏:CSDNToQQCodeCSDNToQQCode

💫 坚果派·红目香薰 倾情分享 🎯 用心打造每一个技术细节,为开发者创造更多价值 📱 让HarmonyOS开发变得更简单、更有趣


✨ 写在前面的话

嗨,亲爱的技术朋友们!👋

我是来自坚果派的红目香薰,一个热爱技术、专注HarmonyOS开发的程序媛。在这个数字化飞速发展的时代,HarmonyOS作为华为自主研发的操作系统,正在改变着我们的数字生活体验。

🌈 为什么要写这个系列?

  • 💡 让复杂的技术变得简单易懂
  • 🚀 帮助更多开发者快速上手HarmonyOS
  • 💝 分享实战经验,避免踩坑
  • 🌟 用代码创造美好,用技术传递温暖

每一个Demo都是我精心设计和反复测试的结果,希望能够为你的HarmonyOS开发之路点亮一盏明灯。✨

今天我们来深入学习HarmonyOS中最实用的布局组件之一——Grid网格组件。从基础网格到复杂的瀑布流布局,让我们一起打造整齐美观的网格界面!


📋 Demo功能说明

在这里插入图片描述
在这里插入图片描述
🎯 核心功能

本Demo展示了HarmonyOS中Grid组件的全面使用方法,包括:

  • 📐 基础网格布局和自适应网格
  • 🎨 自定义网格项样式和间距
  • 📱 响应式网格和多列布局
  • 💫 瀑布流和不规则网格
  • 🎯 网格项的点击和长按事件
  • 🔄 动态添加和删除网格项
  • ✨ 网格动画和过渡效果
  • 🌟 实用的网格应用场景
✨ 特色亮点
  • 🎨 视觉精美:多种网格样式和卡片设计
  • 🚀 性能优化:使用LazyForEach实现大数据网格
  • 📱 响应式设计:自适应不同屏幕尺寸
  • 💡 交互丰富:支持多种手势操作和状态管理
  • 🌟 实用性强:涵盖实际开发中的各种网格场景
🎨 界面展示

界面采用多样化的网格展示:

  • 基础网格:固定列数的规整网格
  • 自适应网格:根据屏幕宽度自动调整列数
  • 瀑布流网格:不同高度的动态网格
  • 功能网格:带图标和操作的实用网格
  • 商品网格:电商风格的商品展示网格
📱 适用场景
  • 🛍️ 电商应用的商品展示网格
  • 📱 应用商店的应用图标网格
  • 📸 相册应用的照片网格
  • 🎮 游戏应用的关卡选择网格
  • ⚙️ 设置页面的功能选项网格
  • 📰 新闻应用的文章卡片网格

🔧 核心代码说明

📁 项目结构
代码语言:javascript
复制
GridDemo/
├── src/
│   ├── main/
│   │   ├── ets/
│   │   │   ├── pages/
│   │   │   │   └── Index.ets          // 主页面
│   │   │   └── entryability/
│   │   └── resources/
│   │       ├── base/
│   │       │   ├── element/
│   │       │   └── media/
│   │       └── rawfile/
│   └── module.json5
🎯 关键技术点
1. Grid组件基础结构
代码语言:javascript
复制
Grid() {
  ForEach(this.dataList, (item: DataItem) => {
    GridItem() {
      // 网格项内容
    }
  })
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(10)
.rowsGap(10)
2. 响应式网格布局
代码语言:javascript
复制
Grid() {
  // 网格内容
}
.columnsTemplate('repeat(auto-fit, minmax(150px, 1fr))')
.width('100%')
.height('100%')
3. 网格项配置
  • columnStart/columnEnd: 网格项的列跨度
  • rowStart/rowEnd: 网格项的行跨度
  • forceRebuild: 强制重建网格项
4. 网格事件处理
  • onItemDragStart: 网格项拖拽开始
  • onItemDrop: 网格项拖拽结束
  • onScrollIndex: 滚动到指定索引
💡 技术要点解析

性能优化策略: 使用LazyForEach和虚拟滚动机制,确保大量数据时的流畅性。

响应式设计: 通过columnsTemplate的auto-fit和minmax实现自适应布局。

瀑布流实现: 结合不同高度的GridItem实现瀑布流效果。


📝 完整Demo代码

🏠 主页面代码
代码语言:javascript
复制
// 数据模型接口
interface GridItemData {
  id: number
  title: string
  subtitle?: string
  icon: string
  color: string
  type?: string
}

interface ProductItemData {
  id: number
  name: string
  price: number
  image: string
  rating: number
  sales: number
}

interface PhotoItemData {
  id: number
  url: string
  width: number
  height: number
  title: string
}

@Entry
@Component
struct Index {
  @State selectedTab: number = 0
  @State gridItems: GridItemData[] = []
  @State products: ProductItemData[] = []
  @State photos: PhotoItemData[] = []

  // 功能网格数据
  private functionItems: GridItemData[] = [
    { id: 1, title: '扫一扫', icon: '📷', color: '#FF6B6B', type: 'scan' },
    { id: 2, title: '付款码', icon: '💳', color: '#4ECDC4', type: 'pay' },
    { id: 3, title: '收款', icon: '💰', color: '#45B7D1', type: 'receive' },
    { id: 4, title: '转账', icon: '💸', color: '#96CEB4', type: 'transfer' },
    { id: 5, title: '充值', icon: '🔋', color: '#FFEAA7', type: 'recharge' },
    { id: 6, title: '理财', icon: '📈', color: '#DDA0DD', type: 'finance' },
    { id: 7, title: '保险', icon: '🛡️', color: '#98D8C8', type: 'insurance' },
    { id: 8, title: '更多', icon: '⋯', color: '#F7DC6F', type: 'more' }
  ]

  // 商品数据
  private productItems: ProductItemData[] = [
    { id: 1, name: '华为Mate60 Pro', price: 6999, image: '📱', rating: 4.9, sales: 1234 },
    { id: 2, name: 'MacBook Pro', price: 12999, image: '💻', rating: 4.8, sales: 567 },
    { id: 3, name: 'AirPods Pro', price: 1999, image: '🎧', rating: 4.7, sales: 890 },
    { id: 4, name: 'iPad Air', price: 4399, image: '📱', rating: 4.6, sales: 456 },
    { id: 5, name: 'Apple Watch', price: 2999, image: '⌚', rating: 4.8, sales: 678 },
    { id: 6, name: '小米电视', price: 3999, image: '📺', rating: 4.5, sales: 234 },
    { id: 7, name: '戴森吹风机', price: 2990, image: '💨', rating: 4.9, sales: 345 },
    { id: 8, name: '任天堂Switch', price: 2099, image: '🎮', rating: 4.7, sales: 567 }
  ]

  // 照片数据
  private photoItems: PhotoItemData[] = [
    { id: 1, url: '🌅', width: 200, height: 150, title: '日出' },
    { id: 2, url: '🌊', width: 200, height: 200, title: '海浪' },
    { id: 3, url: '🏔️', width: 200, height: 180, title: '雪山' },
    { id: 4, url: '🌸', width: 200, height: 160, title: '樱花' },
    { id: 5, url: '🌙', width: 200, height: 220, title: '月夜' },
    { id: 6, url: '🌈', width: 200, height: 140, title: '彩虹' },
    { id: 7, url: '⭐', width: 200, height: 190, title: '星空' },
    { id: 8, url: '🌺', width: 200, height: 170, title: '花朵' }
  ]

  aboutToAppear() {
    this.gridItems = [...this.functionItems]
    this.products = [...this.productItems]
    this.photos = [...this.photoItems]
  }

  build() {
    Column() {
      // 标题区域
      this.buildTitleSection()

      // 标签页
      this.buildTabSection()

      // 内容区域
      if (this.selectedTab === 0) {
        this.buildBasicGrid()
      } else if (this.selectedTab === 1) {
        this.buildProductGrid()
      } else if (this.selectedTab === 2) {
        this.buildPhotoGrid()
      } else {
        this.buildCustomGrid()
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
  }

  // 标题区域
  @Builder
  buildTitleSection() {
    Column({ space: 10 }) {
      Text('🔲 HarmonyOS Grid网格组件')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.White)
        .textAlign(TextAlign.Center)
        .width('100%')
        .padding(20)
        .borderRadius(15)
        .linearGradient({
          angle: 45,
          colors: [['#667eea', 0.0], ['#764ba2', 1.0]]
        })
        .shadow({
          radius: 10,
          color: '#40000000',
          offsetX: 0,
          offsetY: 5
        })

      Text('打造整齐美观的网格界面')
        .fontSize(14)
        .fontColor('#666666')
        .textAlign(TextAlign.Center)
        .fontStyle(FontStyle.Italic)
    }
    .width('100%')
    .backgroundColor(Color.White)
    .padding(20)
    .borderRadius(12)
    .margin({ bottom: 10 })
    .shadow({
      radius: 8,
      color: '#20000000',
      offsetX: 0,
      offsetY: 2
    })
  }

  // 标签页
  @Builder
  buildTabSection() {
    Row({ space: 5 }) {
      Button('功能网格')
        .width(70)
        .height(35)
        .fontSize(12)
        .backgroundColor(this.selectedTab === 0 ? '#3498DB' : '#ECF0F1')
        .fontColor(this.selectedTab === 0 ? Color.White : '#7F8C8D')
        .borderRadius(8)
        .onClick(() => {
          this.selectedTab = 0
        })

      Button('商品网格')
        .width(70)
        .height(35)
        .fontSize(12)
        .backgroundColor(this.selectedTab === 1 ? '#3498DB' : '#ECF0F1')
        .fontColor(this.selectedTab === 1 ? Color.White : '#7F8C8D')
        .borderRadius(8)
        .onClick(() => {
          this.selectedTab = 1
        })

      Button('照片网格')
        .width(70)
        .height(35)
        .fontSize(12)
        .backgroundColor(this.selectedTab === 2 ? '#3498DB' : '#ECF0F1')
        .fontColor(this.selectedTab === 2 ? Color.White : '#7F8C8D')
        .borderRadius(8)
        .onClick(() => {
          this.selectedTab = 2
        })

      Button('自定义')
        .width(70)
        .height(35)
        .fontSize(12)
        .backgroundColor(this.selectedTab === 3 ? '#3498DB' : '#ECF0F1')
        .fontColor(this.selectedTab === 3 ? Color.White : '#7F8C8D')
        .borderRadius(8)
        .onClick(() => {
          this.selectedTab = 3
        })
    }
    .width('100%')
    .justifyContent(FlexAlign.SpaceEvenly)
    .padding({ left: 20, right: 20, bottom: 10 })
  }

  // 基础功能网格
  @Builder
  buildBasicGrid() {
    Column({ space: 20 }) {
      // 4列功能网格
      Column({ space: 10 }) {
        Text('⚡ 快捷功能')
          .fontSize(18)
          .fontWeight(FontWeight.Medium)
          .fontColor('#333333')

        Grid() {
          ForEach(this.gridItems, (item: GridItemData) => {
            GridItem() {
              Column({ space: 8 }) {
                Text(item.icon)
                  .fontSize(32)
                  .width(60)
                  .height(60)
                  .textAlign(TextAlign.Center)
                  .backgroundColor(item.color)
                  .borderRadius(30)
                  .fontColor(Color.White)

                Text(item.title)
                  .fontSize(14)
                  .fontColor('#333333')
                  .fontWeight(FontWeight.Medium)
              }
              .width('100%')
              .padding(15)
              .backgroundColor(Color.White)
              .borderRadius(12)
              .shadow({
                radius: 8,
                color: '#20000000',
                offsetX: 0,
                offsetY: 2
              })
            }
            .onClick(() => {
              console.log(`点击了: ${item.title}`)
            })
          })
        }
        .columnsTemplate('1fr 1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .columnsGap(15)
        .rowsGap(15)
        .width('100%')
        .height(200)
      }
      .width('100%')
      .backgroundColor('#F8F9FA')
      .padding(20)
      .borderRadius(12)

      // 2列大卡片网格
      Column({ space: 10 }) {
        Text('📊 数据统计')
          .fontSize(18)
          .fontWeight(FontWeight.Medium)
          .fontColor('#333333')

        Grid() {
          GridItem() {
            Column({ space: 15 }) {
              Row() {
                Text('📈')
                  .fontSize(24)
                Text('今日收入')
                  .fontSize(16)
                  .fontWeight(FontWeight.Medium)
                  .fontColor('#333333')
                  .layoutWeight(1)
              }
              .width('100%')

              Text('¥12,345')
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .fontColor('#27AE60')

              Text('较昨日 +15.6%')
                .fontSize(12)
                .fontColor('#27AE60')
            }
            .alignItems(HorizontalAlign.Start)
            .width('100%')
            .padding(20)
            .backgroundColor(Color.White)
            .borderRadius(12)
            .shadow({
              radius: 8,
              color: '#20000000',
              offsetX: 0,
              offsetY: 2
            })
          }

          GridItem() {
            Column({ space: 15 }) {
              Row() {
                Text('👥')
                  .fontSize(24)
                Text('新增用户')
                  .fontSize(16)
                  .fontWeight(FontWeight.Medium)
                  .fontColor('#333333')
                  .layoutWeight(1)
              }
              .width('100%')

              Text('1,234')
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .fontColor('#3498DB')

              Text('较昨日 +8.2%')
                .fontSize(12)
                .fontColor('#3498DB')
            }
            .alignItems(HorizontalAlign.Start)
            .width('100%')
            .padding(20)
            .backgroundColor(Color.White)
            .borderRadius(12)
            .shadow({
              radius: 8,
              color: '#20000000',
              offsetX: 0,
              offsetY: 2
            })
          }

          GridItem() {
            Column({ space: 15 }) {
              Row() {
                Text('📦')
                  .fontSize(24)
                Text('订单数量')
                  .fontSize(16)
                  .fontWeight(FontWeight.Medium)
                  .fontColor('#333333')
                  .layoutWeight(1)
              }
              .width('100%')

              Text('567')
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .fontColor('#E67E22')

              Text('较昨日 +12.3%')
                .fontSize(12)
                .fontColor('#E67E22')
            }
            .alignItems(HorizontalAlign.Start)
            .width('100%')
            .padding(20)
            .backgroundColor(Color.White)
            .borderRadius(12)
            .shadow({
              radius: 8,
              color: '#20000000',
              offsetX: 0,
              offsetY: 2
            })
          }

          GridItem() {
            Column({ space: 15 }) {
              Row() {
                Text('⭐')
                  .fontSize(24)
                Text('用户评分')
                  .fontSize(16)
                  .fontWeight(FontWeight.Medium)
                  .fontColor('#333333')
                  .layoutWeight(1)
              }
              .width('100%')

              Text('4.8')
                .fontSize(28)
                .fontWeight(FontWeight.Bold)
                .fontColor('#9B59B6')

              Text('共 2,345 条评价')
                .fontSize(12)
                .fontColor('#9B59B6')
            }
            .alignItems(HorizontalAlign.Start)
            .width('100%')
            .padding(20)
            .backgroundColor(Color.White)
            .borderRadius(12)
            .shadow({
              radius: 8,
              color: '#20000000',
              offsetX: 0,
              offsetY: 2
            })
          }
        }
        .columnsTemplate('1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .columnsGap(15)
        .rowsGap(15)
        .width('100%')
        .height(200)
      }
      .width('100%')
      .backgroundColor('#F8F9FA')
      .padding(20)
      .borderRadius(12)
    }
    .layoutWeight(1)
    .padding({ left: 20, right: 20 })
  }

  // 商品网格
  @Builder
  buildProductGrid() {
    Column({ space: 15 }) {
      Text('🛍️ 热门商品')
        .fontSize(18)
        .fontWeight(FontWeight.Medium)
        .fontColor('#333333')
        .alignSelf(ItemAlign.Start)
        .margin({ left: 20 })

      Grid() {
        ForEach(this.products, (product: ProductItemData) => {
          GridItem() {
            Column({ space: 12 }) {
              // 商品图片
              Text(product.image)
                .fontSize(48)
                .width('100%')
                .height(120)
                .textAlign(TextAlign.Center)
                .backgroundColor('#F5F5F5')
                .borderRadius(8)

              // 商品信息
              Column({ space: 6 }) {
                Text(product.name)
                  .fontSize(14)
                  .fontWeight(FontWeight.Medium)
                  .fontColor('#333333')
                  .maxLines(2)
                  .textOverflow({ overflow: TextOverflow.Ellipsis })

                Row({ space: 5 }) {
                  Text('⭐')
                    .fontSize(12)
                  Text(product.rating.toString())
                    .fontSize(12)
                    .fontColor('#FF9800')
                  Text(`(${product.sales})`)
                    .fontSize(12)
                    .fontColor('#999999')
                }
                .width('100%')

                Text(`¥${product.price}`)
                  .fontSize(16)
                  .fontWeight(FontWeight.Bold)
                  .fontColor('#E74C3C')
              }
              .alignItems(HorizontalAlign.Start)
              .width('100%')
            }
            .width('100%')
            .padding(12)
            .backgroundColor(Color.White)
            .borderRadius(12)
            .shadow({
              radius: 8,
              color: '#20000000',
              offsetX: 0,
              offsetY: 2
            })
          }
          .onClick(() => {
            console.log(`查看商品: ${product.name}`)
          })
        })
      }
      .columnsTemplate('1fr 1fr')
      .columnsGap(15)
      .rowsGap(15)
      .width('100%')
      .layoutWeight(1)
      .padding({ left: 20, right: 20 })
    }
    .layoutWeight(1)
  }

  // 照片网格(瀑布流)
  @Builder
  buildPhotoGrid() {
    Column({ space: 15 }) {
      Text('📸 精美相册')
        .fontSize(18)
        .fontWeight(FontWeight.Medium)
        .fontColor('#333333')
        .alignSelf(ItemAlign.Start)
        .margin({ left: 20 })

      Grid() {
        ForEach(this.photos, (photo: PhotoItemData) => {
          GridItem() {
            Column({ space: 8 }) {
              // 照片
              Text(photo.url)
                .fontSize(40)
                .width('100%')
                .height(photo.height)
                .textAlign(TextAlign.Center)
                .backgroundColor('#F0F0F0')
                .borderRadius(8)

              // 照片标题
              Text(photo.title)
                .fontSize(14)
                .fontColor('#333333')
                .fontWeight(FontWeight.Medium)
                .textAlign(TextAlign.Center)
            }
            .width('100%')
            .padding(10)
            .backgroundColor(Color.White)
            .borderRadius(12)
            .shadow({
              radius: 5,
              color: '#20000000',
              offsetX: 0,
              offsetY: 2
            })
          }
          .onClick(() => {
            console.log(`查看照片: ${photo.title}`)
          })
        })
      }
      .columnsTemplate('1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .width('100%')
      .layoutWeight(1)
      .padding({ left: 20, right: 20 })
    }
    .layoutWeight(1)
  }

  // 自定义网格
  @Builder
  buildCustomGrid() {
    Column({ space: 20 }) {
      // 不规则网格
      Column({ space: 10 }) {
        Text('🎨 创意布局')
          .fontSize(18)
          .fontWeight(FontWeight.Medium)
          .fontColor('#333333')

        Grid() {
          // 大卡片 - 占2x2
          GridItem() {
            Column({ space: 15 }) {
              Text('🎯')
                .fontSize(48)
              Text('主要功能')
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor(Color.White)
              Text('这是一个重要的功能区域')
                .fontSize(14)
                .fontColor('#E0E0E0')
                .textAlign(TextAlign.Center)
            }
            .width('100%')
            .height('100%')
            .padding(20)
            .backgroundColor('#667eea')
            .borderRadius(15)
            .shadow({
              radius: 10,
              color: '#30000000',
              offsetX: 0,
              offsetY: 5
            })
          }
          .columnStart(0)
          .columnEnd(1)
          .rowStart(0)
          .rowEnd(1)

          // 小卡片1
          GridItem() {
            Column({ space: 8 }) {
              Text('📊')
                .fontSize(24)
              Text('统计')
                .fontSize(14)
                .fontWeight(FontWeight.Medium)
                .fontColor('#333333')
            }
            .width('100%')
            .height('100%')
            .padding(15)
            .backgroundColor('#4ECDC4')
            .borderRadius(12)
          }
          .columnStart(2)
          .columnEnd(2)
          .rowStart(0)
          .rowEnd(0)

          // 小卡片2
          GridItem() {
            Column({ space: 8 }) {
              Text('⚙️')
                .fontSize(24)
              Text('设置')
                .fontSize(14)
                .fontWeight(FontWeight.Medium)
                .fontColor('#333333')
            }
            .width('100%')
            .height('100%')
            .padding(15)
            .backgroundColor('#45B7D1')
            .borderRadius(12)
          }
          .columnStart(2)
          .columnEnd(2)
          .rowStart(1)
          .rowEnd(1)

          // 横向卡片
          GridItem() {
            Row({ space: 15 }) {
              Text('📈')
                .fontSize(32)
              Column({ space: 5 }) {
                Text('数据分析')
                  .fontSize(16)
                  .fontWeight(FontWeight.Bold)
                  .fontColor('#333333')
                Text('查看详细报表')
                  .fontSize(12)
                  .fontColor('#666666')
              }
              .alignItems(HorizontalAlign.Start)
              .layoutWeight(1)
            }
            .width('100%')
            .height('100%')
            .padding(15)
            .backgroundColor('#96CEB4')
            .borderRadius(12)
          }
          .columnStart(0)
          .columnEnd(2)
          .rowStart(2)
          .rowEnd(2)
        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr 1fr')
        .columnsGap(10)
        .rowsGap(10)
        .width('100%')
        .height(300)
      }
      .width('100%')
      .backgroundColor('#F8F9FA')
      .padding(20)
      .borderRadius(12)

      // 动态网格
      Column({ space: 10 }) {
        Row() {
          Text('🔄 动态网格')
            .fontSize(18)
            .fontWeight(FontWeight.Medium)
            .fontColor('#333333')
            .layoutWeight(1)

          Button('➕ 添加')
            .height(32)
            .fontSize(12)
            .backgroundColor('#27AE60')
            .borderRadius(16)
            .onClick(() => {
              this.addGridItem()
            })
        }
        .width('100%')

        Grid() {
          ForEach(this.gridItems, (item: GridItemData, index: number) => {
            GridItem() {
              Stack({ alignContent: Alignment.TopEnd }) {
                Column({ space: 8 }) {
                  Text(item.icon)
                    .fontSize(24)
                  Text(item.title)
                    .fontSize(12)
                    .fontColor('#333333')
                }
                .width('100%')
                .height(80)
                .padding(10)
                .backgroundColor(item.color)
                .borderRadius(8)

                // 删除按钮
                Text('✕')
                  .fontSize(12)
                  .fontColor(Color.White)
                  .width(20)
                  .height(20)
                  .textAlign(TextAlign.Center)
                  .backgroundColor('#E74C3C')
                  .borderRadius(10)
                  .margin({ top: 5, right: 5 })
                  .onClick(() => {
                    this.removeGridItem(index)
                  })
              }
            }
          })
        }
        .columnsTemplate('1fr 1fr 1fr')
        .columnsGap(10)
        .rowsGap(10)
        .width('100%')
        .height(200)
      }
      .width('100%')
      .backgroundColor('#F8F9FA')
      .padding(20)
      .borderRadius(12)
    }
    .layoutWeight(1)
    .padding({ left: 20, right: 20 })
  }

  // 添加网格项
  addGridItem() {
    const newItem: GridItemData = {
      id: this.gridItems.length + 1,
      title: `项目${this.gridItems.length + 1}`,
      icon: ['🎯', '⭐', '🔥', '💎', '🚀'][Math.floor(Math.random() * 5)],
      color: ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'][Math.floor(Math.random() * 5)]
    }
    this.gridItems.push(newItem)
  }

  // 删除网格项
  removeGridItem(index: number) {
    this.gridItems.splice(index, 1)
  }
}
⚙️ 配置文件
代码语言:javascript
复制
// module.json5 配置
{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background"
      }
    ]
  }
}

🚀 运行效果

📱 界面展示

运行后的界面将展示:

  • 🔲 渐变色标题,展示Grid组件主题
  • 🏷️ 四个标签页:功能网格、商品网格、照片网格、自定义
  • 功能网格:4x2的快捷功能网格和2x2的数据统计网格
  • 🛍️ 商品网格:2列商品展示,包含图片、评分、价格等信息
  • 📸 照片网格:瀑布流式的照片展示,不同高度的网格项
  • 🎨 自定义网格:不规则布局和动态添加删除功能
✅ 功能验证
  1. 基础功能:切换标签页,查看不同类型网格
  2. 点击交互:点击网格项,查看控制台输出
  3. 响应式布局:调整屏幕尺寸,观察网格自适应
  4. 动态操作:在自定义网格中添加和删除网格项
  5. 视觉效果:观察阴影、圆角、渐变等视觉效果
  6. 瀑布流:查看照片网格的不同高度布局

💡 开发小贴士

🎯 最佳实践
  • 📐 网格设计:合理设置列数和间距,确保视觉平衡
  • 🎨 视觉统一:保持网格项的设计风格一致性
  • 性能优化:大量数据时使用LazyForEach和虚拟滚动
  • 📱 响应式设计:使用auto-fit和minmax实现自适应布局
🚨 常见问题
  1. 网格项大小不一致:检查columnsTemplate和rowsTemplate设置
  2. 间距显示异常:确认columnsGap和rowsGap的值设置
  3. 点击事件无响应:检查onClick事件是否正确绑定
  4. 布局错乱:注意GridItem的columnStart/End和rowStart/End设置
📚 扩展学习
  • 自定义动画:为网格项添加进入和退出动画
  • 拖拽排序:实现网格项的拖拽重排功能
  • 无限滚动:结合LazyForEach实现无限加载

🎉 总结与展望

通过这个Demo,我们学习了:

  • ✨ Grid组件的基础使用和高级特性
  • 🎯 不同类型网格的设计和实现方法
  • 💡 响应式网格布局的开发技巧
  • 🎨 创建美观网格界面的设计原则

Grid组件作为现代移动应用中最重要的布局组件之一,掌握其各种用法对于创建整齐美观的界面至关重要。从简单的功能网格到复杂的瀑布流布局,每一个细节都体现着应用的专业性和用户体验。

希望这个示例能够帮助到正在学习HarmonyOS开发的你!下一期我们将探索更多有趣的UI组件,敬请期待!如果你有任何问题或建议,欢迎在评论区留言交流。


🔗 相关资源


🌟 如果这篇文章对你有帮助,请点赞支持!🌟

让我们一起在HarmonyOS的世界里创造更多可能!


© 2025 坚果派·红目香薰 | 用心分享,用技术创造价值

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ✨ 写在前面的话
  • 📋 Demo功能说明
    • 🎯 核心功能
    • ✨ 特色亮点
    • 🎨 界面展示
    • 📱 适用场景
  • 🔧 核心代码说明
    • 📁 项目结构
    • 🎯 关键技术点
      • 1. Grid组件基础结构
      • 2. 响应式网格布局
      • 3. 网格项配置
      • 4. 网格事件处理
    • 💡 技术要点解析
  • 📝 完整Demo代码
    • 🏠 主页面代码
    • ⚙️ 配置文件
  • 🚀 运行效果
    • 📱 界面展示
    • ✅ 功能验证
  • 💡 开发小贴士
    • 🎯 最佳实践
    • 🚨 常见问题
    • 📚 扩展学习
  • 🎉 总结与展望
  • 🔗 相关资源
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档