HarmonyOS Next 之布局之网格布局(Grid/GridItem)

2025-06-18 14:58:50
112次阅读
0个评论

网格布局是由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。网格布局具有较强的页面均分能力,子组件占比控制能力,是一种重要自适应布局,其使用场景有九宫格图片展示、日历、计算器等。ArkUI提供了Grid容器组件和子组件GridItem,用于构建网格布局。Grid用于设置网格布局相关参数,GridItem定义子组件相关特征。Grid组件支持使用条件渲染、循环渲染、懒加载等渲染控制方式生成子组件。

官方链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-layout-development-create-grid-V5

布局与约束

Grid组件为网格容器,其中容器内每一个条目对应一个GridItem组件,Grid与GridItem组件关系【Grid的子组件必须是GridItem组件】

设置排列方式

  • 通过设置行列数量与尺寸占比可以确定网格布局的整体排列方式。Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。rowsTemplate和columnsTemplate属性值是一个由多个空格和'数字+fr'间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列的宽度。

  • 通过设置行列数量与尺寸占比可以确定网格布局的整体排列方式。Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。rowsTemplate和columnsTemplate属性值是一个由多个空格和'数字+fr'间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列的宽度。

  • 使用Grid构建网格布局时,若没有设置行列数量与占比,可以通过layoutDirection可以设置网格布局的主轴方向,决定子组件的排列方式。此时可以结合minCount和maxCount属性来约束主轴方向上的网格数量

  • 通过Grid的rowsGap和columnsGap可以设置网格布局的行列间距

Grid() {
    ...
}
.columnsGap(10)
.rowsGap(15)

构建可滚动的网格布局

可滚动的网格布局常用在文件管理、购物或视频列表等页面中,如下图所示。在设置Grid的行列数量与占比时,如果仅设置行、列数量与占比中的一个,即仅设置rowsTemplate或仅设置columnsTemplate属性,网格单元按照设置的方向排列,超出Grid显示区域后,Grid拥有可滚动能力。

5-1.gif

如果设置的是columnsTemplate,Grid的滚动方向为垂直方向;如果设置的是rowsTemplate,Grid的滚动方向为水平方向。如上图所示的横向可滚动网格布局,只要设置rowsTemplate属性的值且不设置columnsTemplate属性,当内容超出Grid组件宽度时,Grid可横向滚动进行内容展示。

@Componentstruct Shopping {  
    @State services: Array<string> = ['直播', '进口', ...]  ...
  build() {    
      Column({ space: 5 }) {
          Grid() {        
              ForEach(this.services, (service: string, index) => {          GridItem() {
                  .}
                  .width('25%')
                  }, service => service)      
               }      
              .rowsTemplate('1fr 1fr') // 只设置rowsTemplate属性,当内容超出Grid区域时,可水平滚动。
              .rowsGap(15)
          }
    }
}

控制滚动位置

与新闻列表的返回顶部场景类似,控制滚动位置功能在网格布局中也很常用,例如下图所示日历的翻页功能

5-2.gif

Grid组件初始化时,可以绑定一个Scroller对象,用于进行滚动控制,例如通过Scroller对象的scrollPage方法进行翻页。 在日历页面中,用户在点击“下一页”按钮时,应用响应点击事件,通过指定scrollPage方法的参数next为true,滚动到下一页。

Column({ space: 5 }) {  
    Grid(this.scroller) {
        ...  }
        .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')  ...  Row({space: 20}) {   
            Button('上一页')     
            .onClick(() => {       
                this.scroller.scrollPage({
                    next: false       
                    
                })     
                
            })
   Button('下一页')     
   .onClick(() => {       
       this.scroller.scrollPage({         
           next: true       
        })
   })
}
}
...

性能优化

循环渲染适用于数据量较小的布局场景,当构建具有大量网格项的可滚动网格布局时,推荐使用数据懒加载方式实现按需迭代加载数据,从而提升列表性能。当使用懒加载方式渲染网格时,为了更好的滚动体验,减少滑动时出现白块,Grid组件中也可通过cachedCount属性设置GridItem的预加载数量,只在懒加载LazyForEach中生效。设置预加载数量后,会在Grid显示区域前后各缓存cachedCount*列数个GridItem,超出显示和缓存范围的GridItem会被释放。

Grid() {  
    LazyForEach(this.dataSource, item => {    
        GridItem() {      ...    
            
        }  
     })
}
.cachedCount(3)

网格布局是一个二维的网络,与之类似的还有一个布局——列表布局,区别在于,列表布局可以看做是只有一行,或者一列的特殊网格布局

收藏00

登录 后评论。没有帐号? 注册 一个。