HarmonyOS开发之GridRow&GridCol

GridRow:栅格容器组件,需与结合其子组件GridCol开发,可以适配不同尺寸的设备,让各个设备可以合理的显示,不用过多去做屏幕适配。

一、GridRow参数:breakpoints、columns和gutter

断点:breakpoint

官方:栅格系统以设备的水平宽度(屏幕密度像素值,单位vp)作为断点依据,定义设备的宽度类型,形成了一套断点规则。开发者可根据需求在不同的断点区间实现不同的页面布局效果。

为了便于理解,通过下面的示例代码进行说明。阅览示例代码可知,brerakpoints是GridRow的参数。values和reference是breakpoints的两个成员变量,这两个变量需要结合使用:

1、WindowSize:若reference的值为BreakpointsReference.WindowSize,也是默认值,此值表示是以设备的宽度作为参照,通过屏宽与values内的每个元素进行比较。跟设备有关,因为不同设备,屏宽可能不同。

屏宽属于[0, 300vp)就是xs,

屏宽属于[300, 600vp)就是sm,

屏宽属于[600, 800vp)就是md,

屏宽属于[800, 1000vp)就lg,

屏宽属于[1000, 1200vp)就是xl,

屏宽属于[1200, +∞)就是xxl

2、ComponentSize:若reference的值为BreakpointsReference.ComponentSize,表示是以容器(GridRow)的尺寸作为参照,通过容器width与value内的每个元素进行比较,比较原理与屏宽一致。

需要注意:因为此时是用容器的尺寸的进行比较,所以与当前的设备就无关了(若按设备百分比设置宽度,那跟屏宽还是有关系的)。

重点说明:在示例代码中,values =  ['300vp', '600vp', '800vp', '1000vp', '1200vp'],但values中元素的值是不固定的,理论上只要从小到大排列即可,但这需要跟当前的需求做出相应的调整,因为官方要求最多只能有xs、sm、md、lg、xl、xxl六个断点,所以value中最多只能有五个元素,若只有四个元素,则xxl自动失效,可省去,以此类推,若里面只有一个元素,那就意味着所有情况都只有xs[0, '300vp')和sm['300vp', +∞)两个断点。

span中的xs等断点所传入的值是所占列数,不理解可以暂时先跳过,下面会详细讲解

@Entry

@Component

struct Index {

  @State gridRowWidth: number = 200;

  colors: Color[] = [Color.Red, Color.Yellow, Color.Pink, Color.Orange, Color.Brown, Color.Blue, Color.Orange, Color.Gray]

  build() {

    Column() {

      GridRow({

        breakpoints: {

          value: ['300vp', '600vp', '800vp', '1000vp', '1200vp'],

          // reference: BreakpointsReference.WindowSize, // 以设备尺寸作为参照,跟设备有关

          reference: BreakpointsReference.ComponentSize // 以容器组件尺寸作为参照,绝对尺寸,此处与设备无关

        },

        direction: GridRowDirection.Row // 排列方式:从左至右

      }) {

        ForEach(this.colors, (item: Color, index: Number) => {

          GridCol({

            span: {

              xs: 12, //设备/容器组件宽度在【0, 300) 之间,即为xs。 在最小宽度类型设备上,GridCol占据的GridRow中的12列。

              sm: 6, // 设备/容器组件宽度在【300, 600) 之间,即为sm。在小宽度类型设备上,GridCol占据的GridRow中的6列。

              md: 4, // 设备/容器组件宽度在【600, 800) 之间,即为md。在中等宽度类型设备上,GridCol占据的GridRow中的4列。

              lg: 3, // 设备/容器组件宽度在【800, 1000) 之间,即为lg。在大宽度类型设备上,GridCol占据的GridRow中的3列。

              xl: 2, // 设备/容器组件宽度在【1000, 1300) 之间,即为xl。在特大宽度类型设备上,GridCol占据的GridRow中的2列。

              xxl: 1 // 设备/容器组件宽度在【1200, +∞)之间,即为xxl。在超大宽度类型设备上,GridCol占据的GridRow中的1列。

            }

          }) {

            Row() {

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

                .onClick(() => {

                  this.gridRowWidth += 50; //修改容器组件GridRow的宽度,用于测试,前提:以容器组件为参照

                })

            }.width('100%').height(50)

          }

          .backgroundColor(item)

        }, (item: Color) => item.toString())

      }

      .width(`${this.gridRowWidth}vp`)

      .height(500)

      .backgroundColor('#f5f5f5')

    }

    .width('100%')

  }

}


columns

columns默认值是12,即在不设此参数时,默认12列,也可以自定义

同样通过下面示例代码进行说明:

1、columns是一个复合值类型(number | GridRowColumnOption)。

当columns为number类型时,比如columns: 10,在任何情况下GridRow都被分为10列。下面分别设置GridRow列数为6和10,子元素分别占2列和5列,下面代码就是columns为number类型的示例代码。

当columns类型为GridRowColumnOption时,比如columns: { sm: 4, md: 8 },表示在断点为sm时,GridRow被分为4列;点断为md时,GridRow被分为8列,其他情况默认还是12列。GridRowColumnOption的代码就不做演示了,原理大同小异。

gutter

gutter也是一个复合值类型(Length | GutterOption)。

当gutter为Length类型时,例如:gutter: 20,表示GridCol之间的距离上下左右的距离均为20。

也可以为GutterOption类型,例如:gutter: {x:20, y: 10},表示水平方向间距20,垂直方向间距10。

备注:当一行展示不下时,自动折行。

代码与效果图如下:

@Entry

@Component

struct Index {

  colors: Color[] = [

    Color.Red, Color.Yellow, Color.Pink, Color.Orange,

    Color.Brown, Color.Blue, Color.Yellow, Color.Orange,

    Color.Gray, Color.Pink, Color.Orange, Color.Brown];

  build() {

    Column({space: 30}) {

      GridRow({

        gutter: 20, // GridCol之间的间距为20,也可以设置为{x:20, y: 10},表示水平方向间距20,垂直方向间距10

        columns: 6 // 表示一共把GridRow的宽度分为6列(为了更好理解,可以理解成分为了6份)

      }) {

        ForEach(this.colors, (item: Color, index: Number) => {

          GridCol({

            span: 2 // 共6份,此设置表示占2份的宽度, 所以会展示3列

          }) {

            Row() {

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

            }.width('100%').height(50)

          }

          .backgroundColor(item)

        }, (item: Color) => item.toString())

      }

      .width('100%')

      .height(500)

      .backgroundColor('#f5f5f5')

      GridRow({

        gutter: {x: 20, y: 10}, // 表示为{x:20, y: 10},表示水平方向间距20,垂直方向间距10

        columns: 10 // 10列

      }){

        ForEach(this.colors, (item: Color, index: number) => {

          GridCol({

            span: 5 // 共10份,此设置表示占5份的宽度, 所以会展示2列

          }) {

            Row(){

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

            }

            .backgroundColor(item)

            .width('100%')

            .height(50)

          }

        }, (item: Color) => item.toString())

      }

      .width('100%')

      .height(500)

      .backgroundColor('#f5f5f5')

    }

    .width('100%')

  }

}


3、columns默认值为12,没传入columns时,栅格布局被分成12列,与断点无关了,如下代码与效果图如下:

@Entry

@Component

struct Index {

  colors: Color[] = [

    Color.Red, Color.Yellow, Color.Pink, Color.Orange,

    Color.Brown, Color.Blue, Color.Yellow, Color.Orange,

    Color.Gray, Color.Pink, Color.Orange, Color.Brown];

  build() {

    Column() {

      GridRow() {

        ForEach(this.colors, (item: Color, index: Number) => {

          GridCol() {

            Row() {

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

            }.width('100%').height(50)

          }

          .backgroundColor(item)

        }, (item: Color) => item.toString())

      }

      .width('100%')

      .height(500)

      .backgroundColor('#f5f5f5')

    }

    .width('100%')

  }

}

三、子组件GridCol的参数:span、offset、order

1、span

也是一个复合值类型 (number | GridColColumnOption)。

当span为number类型时,比如span: 4,表示所有情况GridCol都占4列。

当span为GridColColumnOption类型时,如第一份代码中,span{xs: 12}, 表示在对应为xs断点时,当前的GridCol占12列。

2、offset

也是一个复合值类型 (number | GridColColumnOption),表示GridCol相对于前一个GridCol的偏移列数,默认为0。

当类型为number时,GridCol偏移相同列数。例如:offset: 2,偏移量为2列

当类型为GridColColumnOption时,例如:offset: { xs: 1, sm: 2, md: 3, lg: 4 },逻辑与span类型,分断点情况设置的偏移量

当一行的最后偏移量不够时,需要换行继续偏移

3、order

也是一个复合值类型 (number | GridColColumnOption),表示GridCol当前的排序编号,定GridCol排列次序。当GridCol不设置order或者设置相同的order, GridCol按照代码顺序展示。GridCol排序是按order从小到大的排列。未设置order的GridCol依次排序靠前,设置了order的GridCol按照数值从小到大排列。

当类型为number时。例如:order: 2,表示序号为2

当类型为GridColColumnOption时,例如:offset: { xs: 1, sm: 2, md: 3, lg: 4 },逻辑与span类型,分断点情况设置的序号

示例代码和效果图如下:

@Entry

@Component

struct Index {

  colors: Color[] = [

    Color.Red, Color.Yellow, Color.Pink, Color.Orange,

    Color.Brown, Color.Blue, Color.Yellow, Color.Orange,

    Color.Gray, Color.Pink, Color.Orange, Color.Brown];

  build() {

    Column({ space: 30 }) {

      GridRow({

        columns: 10 // 表示一共把GridRow的宽度分为10列

      }) {

        ForEach(this.colors, (item: Color, index: Number) => {

          GridCol({

            span: 2 // 共10份,此设置表示占2份的宽度, 所以会展示5列

          }) {

            Row() {

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

            }.width('100%').height(50)

          }

          .backgroundColor(item)

        }, (item: Color) => item.toString())

      }

      .width('100%')

      .height(500)

      .backgroundColor('#f5f5f5')

      GridRow({

        columns: 10 // 10列

      }) {

        ForEach(this.colors, (item: Color, index: number) => {

          GridCol({

            span: 2,

            offset: 2 // 子组件偏移相同列数2,当一行的最后偏移量不够时,需要换行继续偏移

            // offset: {xs: 2, sm: 3} // 与span属性类似,也支持分断点传值

          }) {

            Row() {

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

            }

            .backgroundColor(item)

            .width('100%')

            .height(50)

          }

        }, (item: Color) => item.toString())

      }

      .width('100%')

      .height(500)

      .backgroundColor('#f5f5f5')

      GridRow({ columns: 12 }) {

        ForEach(this.colors, (item: Color, index: number) => {

          GridCol({

            span: 2,

            order: 12 - index // 与文案相反排列

            // order: { xs: 1, sm: 2, md: 3, lg: 4 } //与span属性类似,也支持分断点传值

          }) {

            Row() {

              Text(index.toString())

                .fontSize(20)

                .fontWeight(FontWeight.Bold)

                .width('100%')

                .textAlign(TextAlign.Center)

            }

            .backgroundColor(item)

            .width('100%')

            .height(50)

          }

        }, (item: Color) => item.toString())

      }

}

    .width('100%')

  }

}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,302评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,563评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,433评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,628评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,467评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,354评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,777评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,419评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,725评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,768评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,543评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,387评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,794评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,032评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,305评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,741评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,946评论 2 336

推荐阅读更多精彩内容