鸿蒙开发应用之网格布局 Grid/GridItem

486 阅读6分钟

Grid:

1. Grid的使用场景:

如果布局是由 很多的 行 和 列 所组成、行列可能需要合并、甚至滚动,就可以使用网格布局来实现。

2. Grid的语法:

网格布局:

Grid(){ GridItem(){} }:

注意点:
  1. Grid的子组件必须是GridItem组件,需要展示的内容设置在 GridItem 内部即可。

  2. GridItem 只能有一个子组件。

  3. 宽高分为 2 种情况:

    a. Grid组件设置了宽高属性,则其尺寸为设置值。

    b. Grid组件没有设置宽高属性,Grid组件的尺寸默认适应其父组件的尺寸。

3. Grid的基本属性:

.columnsTemplate('1fr 1fr 1fr') //设置网格布局列数 数字相加等于几就是分为几份。

.rowsTemplate('1fr 1fr 1fr') //设置网格布局行数 数字相加等于几就是分为几份。

('1fr 1fr 1fr')其解释为共分3份,每(行或者列)各占一份。

('1fr 3fr 1fr')其解释为共分5份,第一(行或者列)占一份,第二(行或者列)占三份,第三(行或者列)占一份。

.columnsGap() number类型 //设置列与列的间距。

.rowsGap() number类型 //设置行与行的间距。

注意

当 .columnsTemplate()和 .rowsTemplate()一起使用时,就会生成一个固定行列样式的网格

当它们各自单独使用时可以形成滚动效果:

  1. 水平(横向)滚动:设置的是rowsTemplate,Grid的滚动方向为水平方向。
  2. 垂直(竖向)滚动:设置的是columnsTemplate,Grid的滚动方向为垂直方向。
案例:完成一个网格横向滚动效果
interface NavItem {
  title: string
  icon: ResourceStr
}

@Entry
@Component
struct Grid03 {
  @State message: string = '滚动';
  navList: NavItem[] = [
    ······
  ]
  build() {
    Column() {
      Text(this.message)
        .fontSize(50)
      Grid() {
        ForEach(this.navList, (item: NavItem) => {
          GridItem() {
            Column() {
              Image(item.icon)
                .width('80%')
              Text(item.title)
                .fontSize(12)
            }
            .height('100%')
          }
          .width('20%')
        })
      }
      .rowsTemplate('1fr 1fr')
      .height(160)
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(5)
      .padding({ bottom: 10 })
      .scrollBar(BarState.Off)
      .scrollBarColor(Color.Yellow)
    }
    .width('100%')
    .height('100%')
    .padding(10)
    .backgroundColor('#f5f5f5')
  }
}
效果图:

image.png

4. GridItem属性:

名称参数类型描述
rowStartnumber指定当前元素起始行号。
rowEndnumber指定当前元素终点行号。
columnStartnumber指定当前元素起始列号。
columnEndnumber指定当前元素终点列号。
4.1 合并行列:

日常开发中除了大小相同的等比例网格布局,由不同大小的网格组成不均匀分布的网格布局场景在实际应用中也十分常见,如下:

image.png

想要实现这个网格就要用到上面所提到的属性。

案例: 将上图变为下图

image.png

image.png

实现代码:

小技巧如何快速生成特定长度的数组

list: string[] = Array.from({ length: 30 })

希望数组多长,length 设置为多少即可

@Entry
@Component
struct Index {
  // 生成 12 个元素的数组
  list:number[]= Array.from({ length: 12 })
  build() {
    Column(){
      Grid() {
        ForEach(this.list, (item: number, index: number) => {
          if (index == 2) {
            GridItem() {
              Text(index + '')
                .fontColor(Color.White)
                .fontSize(30)
            }
            .backgroundColor('#9dc3e6')
            // 第三列开始
            .columnStart(3)
            // 第四列列结束
            .columnEnd(4)
          }
          else if(index==3){
            GridItem() {
              Text(index + '')
                .fontColor(Color.White)
                .fontSize(30)
            }
            .backgroundColor('#9dc3e6')
            // 第二行开始
            .rowStart(2)
            .rowEnd(3)
          }
          else {
            GridItem() {
              Text(index + '')
                .fontColor(Color.White)
                .fontSize(30)
            }
            .backgroundColor('#9dc3e6')
          }
        })
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .rowsTemplate('1fr 1fr 1fr')
      .width('100%')
      .height(260)
      .rowsGap(10)
      .columnsGap(10)
      .padding(10)
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Pink)
  }
}

5. 控制滚动

5.1 代码控制滚动

控制一个网格横向滚动效果

核心步骤:

  1. 创建 Scroller 对象
  2. 设置给 Grid
  3. 调用 Scroller 对象的 scrollPage 方法

实现样式:

  1. // 创建 Scroller 对象

scroller: Scroller = new Scroller()

  1. // 设置给 Grid

Grid(this.scroller) { // ... }

  1. // 通过代码控制

this.scroller.scrollPage({

next:true // 下一页

next:false // 上一页

})

案例:

interface NavItem {
  title: string
  icon: ResourceStr
}

@Entry
@Component
struct Day01_07_Grid03 {
  @State message: string = '滚动';
  navList: NavItem[] = [
   ·······
  ]
  // 准备一个滚动控制的对象
  scroller=new Scroller()
  build() {
    Column() {
      Text(this.message)
        .fontSize(50)
      // 绑定控制对象
      Grid(this.scroller) {
        ForEach(this.navList, (item: NavItem) => {
          GridItem() {
            Column() {
              Image(item.icon)
                .width('80%')
              Text(item.title)
                .fontSize(12)
            }
            .height('100%')
          }
          .width('20%')
        })
      }
      .rowsTemplate('1fr 1fr')
      .height(160)
      .width('100%')
      .backgroundColor(Color.White)
      .borderRadius(5)
      .padding({ bottom: 10 })
      .scrollBar(BarState.Off)
      .scrollBarColor(Color.Yellow)
      Row(){
        Button('上一页')
          .onClick(()=>{
            // 向前滚
            this.scroller.scrollPage({
              next:false
            })
          })
        Button('下一页')
          .onClick(()=>{
            // 向后滚
            this.scroller.scrollPage({
              next:true
            })
          })
      }
    }
    .width('100%')
    .height('100%')
    .padding(10)
    .backgroundColor('#f5f5f5')
  }
}

效果:

image.png

5.2 自定义滚动条

如果默认的滚动条外观无法满足要求,我们还可以进行自定义

自定义有两种方法:

  1. 使用提供的属性调整(可调整属性有限)
  2. 使用 ScrollBar 组件自定义(可定制性高)
5.2.1 使用属性调整

先来看看如何使用属性调整

如果需求只是调整颜色和宽度,或者是关闭滚动条就使用该方式

属性名类型说明
scrollBarBarState设置滚动条状态。默认值:BarState.autoBarState.off 关闭BarState.on 常驻BarState.auto 按需显示
scrollBarColorstringnumberColor设置滚动条的颜色。
scrollBarWidthstringnumber设置滚动条的宽度。宽度设置后,滚动条正常状态和按压状态宽度均为滚动条的宽度值。默认值:4单位:vp

@Entry
@Component
struct DGrid06 {
  // 长度为 30 每一项都为 undefined 的数组
  list: string[] = Array.from({ length: 30 })

  build() {
    Column() {
      Grid() {
        ForEach(this.list, (item: string, index) => {
          GridItem() {
            Text((index + 1).toString())
              .myExtend2()
          }
          .padding(5)
          .height('30%')
          .width('25%')
        })

      }
      .columnsTemplate('1fr 1fr 1fr') // 竖向滚动
      .rowsGap(10)
      .width('100%')
      .height(300)
      .border({ width: 1 })
      .padding(5)
      // 设置改变样式
      .scrollBarWidth(20) // 宽度
      .scrollBarColor(Color.Orange) // 滚颜色
      .scrollBar(BarState.Off) // 关闭
      
    }
    .width('100%')
    .height('100%')
  }
}

@Extend(Text)
function myExtend2() {
  .backgroundColor('#0094ff')
  .width('100%')
  .height('100%')
  .fontSize(30)
  .fontColor(Color.White)
  .textAlign(TextAlign.Center)
}
5.2.2 使用 ScrollBar 组件自定义

核心步骤:

  1. 和 Grid 共用同一个 Scroller
  2. 创建 ScrollBar组件并设置属性
参数名参数类型必填参数描述
scrollerScroller可滚动组件的控制器。用于与可滚动组件进行绑定。
directionScrollBarDirection滚动条的方向,控制可滚动组件对应方向的滚动。默认值:ScrollBarDirection.Vertical
stateBarState滚动条状态。默认值:BarState.Auto

自定义滚动条样式案例实现图:

image.png

核心实现代码:

// 定义一个ScrollBar  (自定义一个滚动条)
ScrollBar({
  // 这个参数要和Grid组件使用同一个scroller对象
  scroller:this.scroller,
  // 水平方向
  direction:ScrollBarDirection.Horizontal,
  // 滚动条常驻
  state:BarState.On
}){
  // 用来定义自定义滚动条的内容
  Column(){}
  .height(5)
  .width(25)
  .backgroundColor(Color.Orange)
  .borderRadius(5)
}
// 这些属性用来控制自定义滚动条外观
.width(50)
.height(5)
.backgroundColor(Color.Gray)
.borderRadius(5)