ui-ts-layout-grid-container-new.md 12.2 KB
Newer Older
S
sienna1128 已提交
1
# 栅格布局
S
sienna1128 已提交
2

L
luoying_ace_admin 已提交
3 4 5 6 7 8 9 10
栅格系统作为一种辅助布局的定位工具,在平面设计和网站设计都起到了很好的作用,对移动设备的界面设计有较好的借鉴作用。总结栅格系统对于移动设备的优势主要有:

1. 给布局提供一种可循的规律,解决多尺寸多设备的动态布局问题。
2. 给系统提供一种统一的定位标注,保证各模块各设备的布局一致性。
3. 给应用提供一种灵活的间距调整方法,满足特殊场景布局调整的可能性。

推荐使用栅格组件[GridRow](../reference/arkui-ts/ts-container-gridrow.md)[GridCol](../reference/arkui-ts/ts-container-gridcol.md)来实现栅格布局效果,
相对于目前已废弃的[GridContainer](../reference/arkui-ts/ts-container-gridcontainer.md)组件,GridRow和GridCol提供了更灵活、更全面的栅格系统实现方案。GridRow为栅格容器组件,只能与栅格子组件GridCol在栅格布局场景中使用。
S
sienna1128 已提交
11

S
sienna1128 已提交
12 13

## 栅格容器GridRow
S
sienna1128 已提交
14 15


S
sienna1128 已提交
16 17 18 19 20 21 22
栅格容器有columns、gutter、direction、breakpoints四个属性。
- columns: 栅格布局的主要定位工具,设置栅格布局的总列数。
- gutter: 设置元素之间的距离,决定内容间的紧密程度。
- direction: 设置栅格子组件在栅格容器中的排列方向。
- breakpoints:以设备宽度为基准,将应用宽度分成了几个不同的区间,即不同的断点。开发者可根据需要在不同的区间下实现不同的页面布局效果。


S
sienna1128 已提交
23
首先通过设置断点,得到一系列断点区间;然后,借助栅格组件能力监听应用窗口大小的变化,判断应用当前处于哪个断点区间,最后调整应用的布局。
S
sienna1128 已提交
24 25 26

### 栅格系统断点

L
luoying_ace_admin 已提交
27 28
栅格系统以设备的水平宽度(屏幕密度像素值,单位vp)作为断点依据,定义设备的宽度类型,形成了一套断点规则。开发者可根据需求在不同的断点区间实现不同的页面布局效果。
栅格系统默认断点将设备宽度分为xs、sm、md、lg四类,尺寸范围如下:
S
sienna1128 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

| 断点名称  | 取值范围(vp)| 
| --------| ------ | 
| xs | [0, 320)   | 
| sm | [320, 520) | 
| md | [520, 840) | 
| lg | [840, +∞)  | 

在GridRow新栅格组件中,允许开发者使用breakpoints自定义修改断点的取值范围,最多支持6个断点,除了默认的四个断点外,
还可以启用xl,xxl两个断点,支持六种不同尺寸(xs, sm, md, lg, xl, xxl)设备的布局设置。

| 断点名称 | 设备描述        |
| ----- | ---------------------------------------- |
| xs  | 最小宽度类型设备。    |
| sm   | 小宽度类型设备。      |
| md   | 中等宽度类型设备。    |
| lg  | 大宽度类型设备。      |
| xl   | 特大宽度类型设备。    |
| xxl | 超大宽度类型设备。    |

- 针对断点位置,开发者根据实际使用场景,通过一个单调递增数组设置。由于breakpoints最多支持六个断点,单调递增数组长度最大为5。

  ```ts
  breakpoints: {value: ["100vp", "200vp"]}
  ```

  表示启用xs、sm、md共3个断点,小于100vp为xs,100vp-200vp为sm,大于200vp为md。
S
sienna1128 已提交
56

S
sienna1128 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
  ```ts
  breakpoints: {value: ["320vp", "520vp", "840vp", "1080vp"]}
  ```

  表示启用xs、sm、md、lg、xl共5个断点,小于320vp为xs,320vp-520vp为sm,520vp-840vp为md,840vp-1080vp为lg,大于1080vp为xl。


- 栅格系统通过监听窗口或容器的尺寸变化进行断点,通过reference设置断点切换参考物。 考虑到应用可能以非全屏窗口的形式显示,以应用窗口宽度为参照物更为通用。

下例中,使用栅格的默认列数12列,通过断点设置将应用宽度分成六个区间,在各区间中,每个栅格子元素占用的列数均不同。效果如图:
  ```ts
GridRow({
  breakpoints: {
    value: ['200vp', '300vp', '400vp', '500vp', '600vp'],
    reference: BreakpointsReference.WindowSize
  }
}) {
     ForEach(this.bgColors, (color, index) => {
       GridCol({
         span: {
           xs: 2,
           sm: 3,
           md: 4,
           lg: 6,
           xl: 8,
           xxl: 12
         }
       }) {
         Row() {
           Text(${index})
         }.width("100%").height("50vp")
       }.backgroundColor(color)
     })
}                                                                    
```
S
sienna1128 已提交
92

S
sienna1128 已提交
93
![](figures/breakpoints.gif)
S
sienna1128 已提交
94 95
  

S
sienna1128 已提交
96 97 98 99 100 101 102 103 104

### 栅格布局的总列数

GridRow中通过columns设置栅格布局的总列数。

- columns默认值为12,当未设置columns时,在任何断点下,栅格布局被分成12列。
   ```ts
  GridRow() {
    ForEach(this.bgColors, (item, index) => {
S
sienna1128 已提交
105 106
      GridCol() {
        Row() {
S
sienna1128 已提交
107 108 109
          Text(`${index + 1}`)
        }.width("100%").height("50")
      }.backgroundColor(item)
S
sienna1128 已提交
110 111 112
    })
  }           
  ```
S
sienna1128 已提交
113

S
sienna1128 已提交
114 115
  ![](figures/columns1.png)

S
sienna1128 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
- 当columns类型为number时,栅格布局在任何尺寸设备下都被分为columns列。下面分别设置栅格布局列数为4和8,子元素默认占一列,效果如下:

  ```ts
  Row() {
    GridRow({ columns: 4 }) {
      ForEach(this.bgColors, (item, index) => {
        GridCol() {
          Row() {
            Text(`${index + 1}`)
          }.width("100%").height("50")
        }.backgroundColor(item)
      })
    }
    .width("100%").height("100%")
    .onBreakpointChange((breakpoint) => {
      this.currentBp = breakpoint
    })
  }
  .height(160)
  .border({ color: Color.Blue, width: 2 })
  .width('90%')
S
sienna1128 已提交
137
  
S
sienna1128 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  Row() {
    GridRow({ columns: 8 }) {
      ForEach(this.bgColors, (item, index) => {
        GridCol() {
          Row() {
            Text(`${index + 1}`)
          }.width("100%").height("50")
        }.backgroundColor(item)
      })
    }
    .width("100%").height("100%")
    .onBreakpointChange((breakpoint) => {
      this.currentBp = breakpoint
    })
  }
  .height(160)
  .border({ color: Color.Blue, width: 2 })
  .width('90%')
  ```
  
  ![](figures/columns2.png)


- 当columns类型为GridRowColumnOption时,支持下面六种不同尺寸(xs, sm, md, lg, xl, xxl)设备的总列数设置,各个尺寸下数值可不同。
S
sienna1128 已提交
162

S
sienna1128 已提交
163 164 165 166 167 168 169 170 171 172
  ```ts
  GridRow({ columns: { sm: 4, md: 8 }, breakpoints: { value: ['200vp', '300vp', '400vp', '500vp', '600vp'] } }) {
    ForEach(this.bgColors, (item, index) => {
      GridCol() {
        Row() {
          Text(`${index + 1}`)
        }.width("100%").height("50")
      }.backgroundColor(item)
    })
  }
S
sienna1128 已提交
173
  ```
S
sienna1128 已提交
174
  ![](figures/columns3.gif)
S
sienna1128 已提交
175

S
sienna1128 已提交
176
  如上,若只设置sm, md的栅格总列数,则较小的尺寸使用默认columns值12,较大的尺寸使用前一个尺寸的columns。这里只设置sm:8, md:10,则较小尺寸的xs:12,较大尺寸的参照md的设置,lg:10, xl:10, xxl:10。
S
sienna1128 已提交
177

S
sienna1128 已提交
178
### 栅格子组件间距
S
sienna1128 已提交
179

S
sienna1128 已提交
180
GridRow中通过gutter设置子元素在水平和垂直方向的间距。
S
sienna1128 已提交
181

S
sienna1128 已提交
182
- 当gutter类型为number时,同时设置栅格子组件间水平和垂直方向边距且相等。下例中,设置子组件水平与垂直方向距离相邻元素的间距为10。
S
sienna1128 已提交
183

S
sienna1128 已提交
184 185
  ```ts
   GridRow({ gutter: 10 }){}
S
sienna1128 已提交
186
  ```
S
sienna1128 已提交
187

S
sienna1128 已提交
188 189
  ![](figures/gutter1.png)
  
S
sienna1128 已提交
190 191
  

S
sienna1128 已提交
192 193 194
- 当gutter类型为GutterOption时,单独设置栅格子组件水平垂直边距,x属性为水平方向间距,y为垂直方向间距。

  ```ts
S
sienna1128 已提交
195 196 197
  GridRow({ gutter: { x: 20, y: 50 } }){}
  ```

S
sienna1128 已提交
198
  ![](figures/gutter2.png)  
S
sienna1128 已提交
199

S
sienna1128 已提交
200 201


S
sienna1128 已提交
202
### 排列方向
S
sienna1128 已提交
203

S
sienna1128 已提交
204
通过GridRow的direction属性设置栅格子组件在栅格容器中的排列方向。
S
sienna1128 已提交
205

S
sienna1128 已提交
206
- 子组件默认从左往右排列。
S
sienna1128 已提交
207

S
sienna1128 已提交
208
  ```ts
S
sienna1128 已提交
209 210 211 212
  GridRow({ direction: GridRowDirection.Row }){}
  ```
  ![](figures/direction1.png)

S
sienna1128 已提交
213
- 子组件从右往左排列。
S
sienna1128 已提交
214

S
sienna1128 已提交
215
  ```ts
S
sienna1128 已提交
216 217 218 219 220
  GridRow({ direction: GridRowDirection.RowReverse }){}
  ```
  
  ![](figures/direction2.png)

S
sienna1128 已提交
221

S
sienna1128 已提交
222

S
sienna1128 已提交
223
## 栅格子组件GridCol
S
sienna1128 已提交
224

S
sienna1128 已提交
225
GridCol组件作为GridRow组件的子组件,通过给GridCol传参或者设置属性两种方式,设置span,offset,order的值。
S
sienna1128 已提交
226

S
sienna1128 已提交
227
- span的设置
S
sienna1128 已提交
228

S
sienna1128 已提交
229
  ```ts
S
sienna1128 已提交
230 231 232 233 234
  GridCol({ span: 2 }){}
  GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }){}
  GridCol(){}.span(2)
  GridCol(){}.span({ xs: 1, sm: 2, md: 3, lg: 4 })
  ```
S
sienna1128 已提交
235

S
sienna1128 已提交
236
- offset的设置
S
sienna1128 已提交
237

S
sienna1128 已提交
238
  ```ts
S
sienna1128 已提交
239 240 241 242 243
  GridCol({ offset: 2 }){}
  GridCol({ offset: { xs: 2, sm: 2, md: 2, lg: 2 } }){}
  GridCol(){}.offset(2)
  GridCol(){}.offset({ xs: 1, sm: 2, md: 3, lg: 4 }) 
  ```
S
sienna1128 已提交
244

S
sienna1128 已提交
245
- order的设置
S
sienna1128 已提交
246

S
sienna1128 已提交
247
  ```ts
S
sienna1128 已提交
248 249 250 251 252
  GridCol({ order: 2 }){}
  GridCol({ order: { xs: 1, sm: 2, md: 3, lg: 4 } }){}
  GridCol(){}.order(2)
  GridCol(){}.order({ xs: 1, sm: 2, md: 3, lg: 4 })
  ```
S
sienna1128 已提交
253

S
sienna1128 已提交
254
  下面使用传参的方式演示各属性的使用。
S
sienna1128 已提交
255

S
sienna1128 已提交
256
### span
S
sienna1128 已提交
257

S
sienna1128 已提交
258
子组件占栅格布局的列数,决定了子组件的宽度,默认为1。
S
sienna1128 已提交
259

S
sienna1128 已提交
260
- 当类型为number时,子组件在所有尺寸设备下占用的列数相同。
S
sienna1128 已提交
261

S
sienna1128 已提交
262
  ```ts
S
sienna1128 已提交
263 264 265 266
  GridRow({ columns: 8 }) {
    ForEach(this.bgColors, (color, index) => {
      GridCol({ span: 2 }) {      
        Row() {
S
sienna1128 已提交
267
          Text(${index})
S
sienna1128 已提交
268 269 270 271 272
        }.width("100%").height("50vp")          
      }
      .backgroundColor(color)
    })
  }                
S
sienna1128 已提交
273
  ```
S
sienna1128 已提交
274 275 276

  ![](figures/span1.png)

S
sienna1128 已提交
277
- 当类型为GridColColumnOption时,支持六种不同尺寸(xs, sm, md, lg, xl, xxl)设备中子组件所占列数设置,各个尺寸下数值可不同。
S
sienna1128 已提交
278

S
sienna1128 已提交
279
  ```ts
S
sienna1128 已提交
280 281 282 283
  GridRow({ columns: 8 }) {
    ForEach(this.bgColors, (color, index) => {
      GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }) {      
        Row() {
S
sienna1128 已提交
284
          Text(${index})
S
sienna1128 已提交
285 286 287 288 289 290 291
        }.width("100%").height("50vp")          
      }
      .backgroundColor(color)
    })
  }                
  ```

S
sienna1128 已提交
292
  ![](figures/span2.gif)
S
sienna1128 已提交
293 294

### offset
S
sienna1128 已提交
295

S
sienna1128 已提交
296
栅格子组件相对于前一个子组件的偏移列数,默认为0。
S
sienna1128 已提交
297
- 当类型为number时,子组件偏移相同列数。
S
sienna1128 已提交
298

S
sienna1128 已提交
299
  ```ts
S
sienna1128 已提交
300 301 302 303 304 305 306 307 308 309
  GridRow() {
    ForEach(this.bgColors, (color, index) => {
      GridCol({ offset: 2 }) {      
        Row() {
          Text("" + index)
        }.width("100%").height("50vp")          
      }
      .backgroundColor(color)
    })
  }                
S
sienna1128 已提交
310
  ```
S
sienna1128 已提交
311 312

  ![](figures/offset1.png)
S
sienna1128 已提交
313

S
sienna1128 已提交
314
  栅格默认分成12列,每一个子组件默认占1列,偏移2列,每个子组件及间距共占3列,一行放四个子组件。
S
sienna1128 已提交
315

S
sienna1128 已提交
316

S
sienna1128 已提交
317
- 当类型为GridColColumnOption时,支持六种不同尺寸(xs, sm, md, lg, xl, xxl)设备中子组件所占列数设置,各个尺寸下数值可不同。
S
sienna1128 已提交
318

S
sienna1128 已提交
319
  ```ts
S
sienna1128 已提交
320 321 322 323 324 325 326 327 328 329 330
  GridRow() {
    ForEach(this.bgColors, (color, index) => {
      GridCol({ offset: { xs: 1, sm: 2, md: 3, lg: 4 } }) {      
        Row() {
          Text("" + index)
        }.width("100%").height("50vp")          
      }
      .backgroundColor(color)
    })
  }                
  ```
S
sienna1128 已提交
331

S
sienna1128 已提交
332 333 334
  ![](figures/offset2.gif)

### order
S
sienna1128 已提交
335 336

  栅格子组件的序号,决定子组件排列次序。当子组件不设置order或者设置相同的order, 子组件按照代码顺序展示。当子组件设置不同的order时,order较大的组件在前,较小的在后。
S
sienna1128 已提交
337
  当子组件部分设置order,部分不设置order时,未设置order的子组件依次排序靠前,设置了order的子组件按照数值从大到小排列。
S
sienna1128 已提交
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365


- 当类型为number时,子组件在任何尺寸下排序次序一致。

  ```ts
  GridRow() {
    GridCol({ order: 5 }) {
      Row() {
        Text("1")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Red)
    GridCol({ order: 4 }) {
      Row() {
        Text("2")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Orange)
    GridCol({ order: 3 }) {
      Row() {
        Text("3")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Yellow)
    GridCol({ order: 2 }) {
      Row() {
        Text("4")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Green)
  }            
  ```
S
sienna1128 已提交
366

S
sienna1128 已提交
367
  ![](figures/order1.png)
S
sienna1128 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
- 当类型为GridColColumnOption时,支持六种不同尺寸(xs, sm, md, lg, xl, xxl)设备中子组件排序次序设置。

  ```ts
  GridRow() {
    GridCol({ order: { xs:1, sm:5, md:3, lg:7}}) {
      Row() {
        Text("1")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Red)
    GridCol({ order: { xs:2, sm:2, md:6, lg:1} }) {
      Row() {
        Text("2")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Orange)
    GridCol({ order: { xs:3, sm:3, md:1, lg:6} }) {
      Row() {
        Text("3")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Yellow)
    GridCol({ order: { xs:4, sm:4, md:2, lg:5} }) {
      Row() {
        Text("4")
      }.width("100%").height("50vp")
    }.backgroundColor(Color.Green)
  } 
  ```
S
sienna1128 已提交
394 395 396

  ![](figures/order2.gif)

S
sienna1128 已提交
397