HarmonyOS鸿蒙Next中grid布局如何实现动态异形布局,根据数据标识,动态设置宽高占比

HarmonyOS鸿蒙Next中grid布局如何实现动态异形布局,根据数据标识,动态设置宽高占比

接口返回100条数据,每个数据item都有一个标识符mark,当mark=0时 1:1,当mark=1是3:1,当mark=2时是2:2,如何根据mark动态设置gridItem的占比呢?如想要实现图片中的效果,应该怎么操作呢?

cke_3788.jpg

cke_4253.png


更多关于HarmonyOS鸿蒙Next中grid布局如何实现动态异形布局,根据数据标识,动态设置宽高占比的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

【背景知识】

onGetRectByIndex:设置指定索引index对应的GridItem的位置及大小[rowStart,columnStart,rowSpan,columnSpan]。其中rowStart为行起始位置,columnStart为列起始位置,无单位。rowSpan为GridItem占用的行数,columnSpan为GridItem占用的列数,无单位。

【解决方案】

可以使用GridLayoutOptions中的onGetRectByIndex指定GridItem的位置和大小。 示例代码如下:

@Entry
@Component
struct GridExample {
  @State numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
  @State showIndexArr: Array<[number, number, number, number]> = [
    [0, 0, 1, 4], // Index为0时:行起始位置0,列起始位置0,GridItem占用1行,GridItem占用4列
    [1, 0, 2, 1],
    [1, 1, 2, 1],
    [1, 2, 2, 1],
    [1, 3, 2, 1],
    [3, 0, 2, 1],
    [3, 1, 2, 1],
    [3, 2, 2, 1],
    [3, 3, 2, 1],
    [5, 0, 3, 4],
    [8, 0, 1, 4]
  ]
  layoutOptions: GridLayoutOptions = {
    regularSize: [1, 1],
    onGetRectByIndex: (index: number) => this.showIndexArr[index] || [1, 1, 1, 1]
  }

  build() {
    Column({ space: 4 }) {
      Grid(undefined, this.layoutOptions) {
        ForEach(this.numbers, (day: string) => {
          GridItem() {
            Text(day)
              .fontSize(16)
              .backgroundColor(0xF9CF93)
              .width('100%')
              .height("100%")
              .textAlign(TextAlign.Center)
          }
          .height("100%")
          .width('100%')
        }, (day: string) => day)
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .width('90%')
      .backgroundColor(0xFAEEE0)
      .height(500)
    }.width('100%').margin({ top: 5 })
  }
}

【总结】

参考相关文档,根据mark为不同的item设置相对应的[rowStart,columnStart,rowSpan,columnSpan],可实现效果。

更多关于HarmonyOS鸿蒙Next中grid布局如何实现动态异形布局,根据数据标识,动态设置宽高占比的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS NEXT中实现动态异形Grid布局,可使用ArkUI的Grid组件结合自定义组件。通过Grid的columnsTemplate和rowsTemplate属性动态设置行列模板,利用数据标识控制布局比例。

关键步骤:

  1. 在Grid组件中绑定数据源
  2. 使用@Builder动态创建子组件
  3. 根据数据中的标识字段(如type)判断布局样式
  4. 通过GridItem的columnStart/columnEnd和rowStart/rowEnd控制单元格跨度

示例代码片段:

Grid() {
  ForEach(data, item => {
    GridItem() {
      CustomCell(item)
    }.columnStart(item.startCol)
     .columnEnd(item.endCol)
  })
}
.columnsTemplate("1fr 2fr 1fr")

在HarmonyOS Next中实现动态异形Grid布局,可以通过GridContainer配合条件渲染实现。以下是解决方案:

  1. 使用GridContainer作为容器,设置columnsTemplate"1fr 1fr 1fr"等比例列

  2. 根据mark值动态设置GridItem的rowSpancolumnSpan属性:

@Entry
@Component
struct DynamicGrid {
  @State items: Array<{mark: number}> = [...] // 你的数据源

  build() {
    GridContainer() {
      ForEach(this.items, (item) => {
        GridItem() {
          // 你的内容组件
        }
        .rowSpan(this.getRowSpan(item.mark))
        .columnSpan(this.getColumnSpan(item.mark))
      })
    }
    .columnsTemplate("1fr 1fr 1fr")
  }

  private getRowSpan(mark: number): number {
    switch(mark) {
      case 0: return 1; // 1:1比例
      case 1: return 1; // 3:1比例
      case 2: return 2; // 2:2比例
      default: return 1;
    }
  }

  private getColumnSpan(mark: number): number {
    switch(mark) {
      case 0: return 1;
      case 1: return 3;
      case 2: return 2;
      default: return 1;
    }
  }
}
  1. 对于更复杂的宽高比控制,可以结合aspectRatio属性:
GridItem()
  .aspectRatio(mark === 0 ? 1 : (mark === 1 ? 3 : 2))

这种方法通过动态计算每个GridItem的跨行跨列数,配合比例约束,可以实现图片中展示的异形布局效果。

回到顶部