HarmonyOS-ArkUI Grip组件

打印 上一主题 下一主题

主题 1633|帖子 1633|积分 4899

我们在学习List的时候,已经捎带引入了Grid。解说如下图所示:


也就是,如果一个表,长宽根本都是一致的,那么此时可以完全不消Grid也可以实现,并且,优先考虑的就是List。
如果List实现不了的情况下,我们才会考虑到要不要用Grid来完成。那么grid究竟存在什么List不具备的本领呢?
我们起首看一张图就大致明白了。 Grid组件可以实现的本领:


此中中央的那张布局结构,就是Grid与List相比有明显差别的地方。当我们有需求,要求每一个子组件并非是严格的相等的宽高时,采用Grid组件是比力合适的。
好有了大概得了解 ,我们接下来来学习一下,这个组件,并掌握这么犬牙交错的界面应该怎么搭建,搭建的时候,组件的其他属性限制。

概述

网格布局是由“行”和“列”分割的单元格构成,通过指定项目所在的单元格做出各种各样的布局,网格布局具有较强的页面均分本领,子组件占比控制本领,是一种紧张的自顺应布局,利用场景如,九宫格,计算器,日历等。
ArkUI为网格布局提供了相关的组件,Grid以及GridItem。Grid用来设置布局相关参数,GridItem定义子组件相关特征。Grid组件也支持,条件渲染,循环渲染,和懒加载等方式来生成组件.
Grid与GridItem组件的关系:


Grid组件支持自定义行数和每行每列尺寸占比,设置子组件可以高出几行和几列,同时提供了水平和垂直的布局本领。当网格容器组件发生厘革时,所有组件以及间距会等比例调整,从而实现布局的自顺应本领。根据Grid的这些布局本领,可以构建出差别的网格样式。


设置分列方式

Grid的亮点就是用户可以设置分列方式,下面我们学习一下应该怎么分列。
设置行列数量与占比

起首看看效果图


Grid提供了rowsTemplate和 columnsTemplate属性,用来设置网格布局的行数,行占比,列数,列占比。他们的值的格式是一个数组,数组的数量即可体现行大概列的数量,数组的内容则代表占比。
上图,构建的是一个三行三列的网格,此中每一行的第二列都是第一行的2倍宽度。以是我们可以如许写。
  1. @Entry
  2. @Component
  3. struct GridItemPage {
  4.   @State numberList: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8']
  5.   build() {
  6.     Stack() {
  7.         Grid() {
  8.          ForEach(this.numberList, (item:string)=>{
  9.            GridItem(){
  10.              Text(item)
  11.                .backgroundColor(Color.Pink)
  12.            }
  13.            .backgroundColor(Color.Brown)
  14.          }, (item:string)=> item.toString())
  15.         }
  16.         // 注意中间一定不要有逗号,有逗号,渲染就会出问题。就是空格分开的.
  17.         // 另外,展示的数量就是这个行列相乘的数量.即使给定的数据很多,也就会展示这几个元素,且没有滚动交互.
  18.         .rowsTemplate('1fr 1fr 1fr')
  19.         .columnsTemplate('1fr 2fr 1fr')
  20.         .rowsGap(10)
  21.       .columnsGap(10)
  22.       }
  23.   }
  24. }
复制代码


注意:
当Grid设置了rowsTemplate和columnsTemplate之后,相称于Grid的方向大小已经确定了,以是以下几个不见效


  • layoutDirection
  • maxCount
  • minCount
  • cellLengh
另外,因为设置了rowsTemplate和columnsTemplate之后,相称于展示的总量已经固定死了,所以Grid的滚动效果也不会被触发,上述界面是不可以滚动的。
构建可滚动的网格布局



可滚动的网格布局,在首页大概某一个紧张的Tab页中用到的是比力多的。这个实现也会用到我们上文讲的 rowsTemplete大概 columnsTemplete,但是利用的时候有个特殊的就是,只用此中一个,系统会因为没有另外一个而造成开放式的这种情况,当内容超出了所能显示的,就会有滚动效果了。



  • 仅仅设置columnsTemplete: 那么就代表列是固定死了, 只能在行上进行发挥,以是滚动是上下滚动,行数随着内容有多少,就会有相应的几行。
  • 仅仅设置rowsTemplete: 那么就代表行已经被固定死了,只能在列进行发挥,以是滚动的时候是左右滚动,列数随着内容有多少,就会有相应的多少列。
  1. @Entry
  2. @Component
  3. struct GridItemPage {
  4.   @State numberList: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8']
  5.   build() {
  6.     Stack() {
  7.         Grid() {
  8.          ForEach(this.numberList, (item:string)=>{
  9.            GridItem(){
  10.              Text(item)
  11.                .backgroundColor(Color.Pink)
  12.            }
  13.            .width(100)
  14.            .height(100)
  15.            .backgroundColor(Color.Brown)
  16.          }, (item:string)=> item.toString())
  17.         }
  18.         // 注意中间一定不要有逗号,就是空格分开的.
  19.         // 另外,展示的数量就是这个行列相乘的数量.即使给定的数据很多,也就会展示这几个元素,且没有滚动交互.
  20.         .rowsTemplate('1fr 1fr')
  21.         // .columnsTemplate('1fr 2fr 1fr')
  22.         .rowsGap(10)
  23.       .columnsGap(10)
  24.       .width('100%')
  25.       .height('auto')
  26.       }
  27.       .width('100%')
  28.     .height(200)
  29.   }
  30. }
复制代码


可以观察下此时的排布,是纵向排布的!我们在写代码的时候注意下排布方向。
不均匀网格布局



我们可以通过创建Grid组件时传入GridLayoutOptions实现上图所示的,单个网格高出多行多列的场景,设置方式如下:

  1. layoutOptions: GridLayoutOptions = {
  2.   regularSize: [1, 1],
  3.   onGetRectByIndex: (index: number) => {
  4.     if (index == key1) { // key1是“0”按键对应的index
  5.       return [6, 0, 1, 2]; // [rowStart,columnStart,rowSpan,columnSpan] 格式
  6.     } else if (index == key2) { // key2是“=”按键对应的index
  7.       return [5, 3, 2, 1];
  8.     }
  9.     // ...
  10.     // 这里需要根据具体布局返回其他item的位置
  11.   }
  12. }
  13. Grid(undefined, this.layoutOptions) {
  14.   // ...
  15. }
  16. .columnsTemplate('1fr 1fr 1fr 1fr')
  17. .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
复制代码
[rowStart,columnStart,rowSpan,columnSpan] 格式解说


  • rowStart 当前元素起始行号
  • columStart 当前元素实在列号
  • rowSpan 当前元素占用的行数
  • columSpan 当前元素占用的列数
如果一个onGetRectByIndex回调,返回的结果是 [6, 0, 1, 2 ]也就是告知,在布局第6排第0列的数据时,它要站一行,两列的大小。
就像下方的计算器,0 的位置,就可以这么描述。


设置主轴方向

如果不做了解的话,我们大概会有一个迷惑。就是网格布局的主轴方向,有必要么?它会影响什么呢? 答案是影响排布次序。如图所示。



Grid设置主轴方向的属性是layoutDirection, 同时要搭配 maxCountminCount来利用


  • layoutDirection 设置主轴方向。
  • maxCount: 主轴方向最大可以排几个格。
  • minCount: 主轴方向最小可以排几个格。
  1. Grid() {
  2.   // ...
  3. }
  4. .maxCount(3)
  5. .layoutDirection(GridDirection.Row)
复制代码
分析


  • layoutDirection属性仅在不设置rowsTemplate和columnsTemplate时见效,此时元素在layoutDirection方向上分列。
  • 仅设置rowsTemplate时,Grid主轴为水平方向,交叉轴为垂直方向。
  • 仅设置columnsTemplate时,Grid主轴为垂直方向,交叉轴为水平方向。

上文可见,Grid在这种情况下,子组件的数量大概是变更的,以是约束了行大概列的铺排形式。相称于开放式布局。以是我们在约束的时候最好给一个最大可以排几个格子这种值。
设置行列间距

这个很简单,就是columnsGap列间距, rowsGap行间距。



  1. Grid() {
  2.   // ...
  3. }
  4. .columnsGap(10)
  5. .rowsGap(15)
复制代码

控制滚动位置

与消息列表返回到顶部比力相似,滚动位置功能在网格布局中也比力常用,比如日历中的翻页功能。


实现方式,我们记住,凡是滚动控制,都离不开滚动控制器。我们在用系统组件的时候,但凡遇到滚动控制的时候都应该向这个方向来考虑。只是详细的控制器范例有区别,控制的内容细节有区别。套路是大差不差的。在这个案例中我们也是,在Grid构建的时候就会传入一个Scroller。这个跟List是一样的。
  1. @Entry
  2. @Component
  3. struct GridItemPage {
  4.   private gridScroller:Scroller = new Scroller()
  5.   @State numberList: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8']
  6.   build() {
  7.     Column(){
  8.         Grid(this.gridScroller) {
  9.          ForEach(this.numberList, (item:string)=>{
  10.            GridItem(){
  11.              Text(item)
  12.                .backgroundColor(Color.Pink)
  13.            }
  14.            .width(100)
  15.            .height(100)
  16.            .backgroundColor(Color.Brown)
  17.          }, (item:string)=> item.toString())
  18.         }
  19.         // 注意中间一定不要有逗号,就是空格分开的.
  20.         // 另外,展示的数量就是这个行列相乘的数量.即使给定的数据很多,也就会展示这几个元素,且没有滚动交互.
  21.         .rowsTemplate('1fr 1fr')
  22.         // .columnsTemplate('1fr 2fr 1fr')
  23.         .rowsGap(10)
  24.       .columnsGap(10)
  25.       .width('100%')
  26.       .height('30%')
  27.       Row(){
  28.         Button("上一页")
  29.           .width(100)
  30.           .height('wrap')
  31.           .onClick(()=>{
  32.             this.gridScroller.scrollPage({
  33.               next: false
  34.             })
  35.           })
  36.         Button("下一页")
  37.           .width(100)
  38.           .height('wrap')
  39.           .onClick(()=>{
  40.             this.gridScroller.scrollPage(
  41.               {next: true}
  42.             )
  43.           })
  44.       }
  45.       .width('100%')
  46.       .justifyContent(FlexAlign.SpaceEvenly)
  47.       .margin({top: 20})
  48.       }
  49.   }
  50. }
复制代码

Grid性能优化-懒加载

这个也就是和List的优化方式如出一辙,就是设置懒加载,然后设置加载数量。
  1. Grid() {
  2.   LazyForEach(this.dataSource, () => {
  3.     GridItem() {
  4.     }
  5.   })
  6. }
  7. .cachedCount(3)
复制代码
属性互斥关系及注意事项总结






























免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表