1# Grid 2 3网格容器,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。 4 5> **说明:** 6> 7> 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9 10## 子组件 11 12仅支持[GridItem](ts-container-griditem.md)子组件,支持渲染控制类型([if/else](../../../quick-start/arkts-rendering-control-ifelse.md)、[ForEach](../../../quick-start/arkts-rendering-control-foreach.md)、[LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md)和[Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md))。 13 14> **说明:** 15> 16> Grid子组件的索引值计算规则: 17> 18> 按子组件的顺序依次递增。 19> 20> if/else语句中,只有条件成立分支内的子组件会参与索引值计算,条件不成立分支内的子组件不计算索引值。 21> 22> ForEach/LazyForEach和Repeat语句中,会计算展开所有子节点索引值。 23> 24> [if/else](../../../quick-start/arkts-rendering-control-ifelse.md)、[ForEach](../../../quick-start/arkts-rendering-control-foreach.md)、[LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md)和[Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md)发生变化以后,会更新子节点索引值。 25> 26> Grid子组件的visibility属性设置为Hidden或None时依然会计算索引值。 27> 28> Grid子组件的visibility属性设置为None时不显示,但依然会占用子组件对应的网格。 29> 30> Grid子组件设置position属性,会占用子组件对应的网格,子组件将显示在相对Grid左上角偏移position的位置。该子组件不会随其对应网格滚动,在对应网格滑出Grid显示范围外后不显示。 31> 32> 当Grid子组件之间留有空隙时,会根据当前的展示区域尽可能填补空隙,因此GridItem可能会随着网格滚动而改变相对位置。 33 34## 接口 35 36Grid(scroller?: Scroller, layoutOptions?: GridLayoutOptions) 37 38**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 39 40**系统能力:** SystemCapability.ArkUI.ArkUI.Full 41 42**参数:** 43 44| 参数名 | 类型 | 必填 | 说明 | 45| -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | 46| scroller | [Scroller](ts-container-scroll.md#scroller) | 否 | 可滚动组件的控制器。用于与可滚动组件进行绑定。<br/>**说明:** <br/>不允许和其他滚动类组件,如:[List](ts-container-list.md)、[Grid](ts-container-grid.md)、[Scroll](ts-container-scroll.md)等绑定同一个滚动控制对象。 | 47| layoutOptions<sup>10+</sup> | [GridLayoutOptions](#gridlayoutoptions10对象说明) | 否 | Grid布局选项。 | 48 49## GridLayoutOptions<sup>10+</sup>对象说明 50 51**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 52 53**系统能力:** SystemCapability.ArkUI.ArkUI.Full 54 55布局选项。其中,irregularIndexes和onGetIrregularSizeByIndex可对仅设置rowsTemplate或columnsTemplate的Grid使用,可以指定一个index数组,并为其中的index对应的GridItem设置其占据的行数与列数,使用方法参见[示例3](#示例3可滚动grid设置跨行跨列节点);onGetRectByIndex可对同时设置rowsTemplate和columnsTemplate的Grid使用,为指定的index对应的GridItem设置位置和大小,使用方法参见[示例1](#示例1固定行列grid)。 56 57| 名称 | 类型 | 必填 | 说明 | 58| ----- | ------- | ---- | --------------------- | 59| regularSize | [number, number] | 是 | 大小规则的GridItem在Grid中占的行数和列数,只支持占1行1列即[1, 1]。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 60| irregularIndexes | number[] | 否 | 指定的GridItem索引在Grid中的大小是不规则的。当不设置onGetIrregularSizeByIndex时,irregularIndexes中GridItem的默认大小为垂直滚动Grid的一整行或水平滚动Grid的一整列。 <br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 61| onGetIrregularSizeByIndex | (index: number) => [number, number] | 否 | 配合irregularIndexes使用,设置不规则GridItem占用的行数和列数。开发者可为irregularIndexes中指明的index对应的GridItem设置占用的行数和列数。在API version 12之前,垂直滚动Grid不支持GridItem占多行,水平滚动Grid不支持GridItem占多列。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 62| onGetRectByIndex<sup>11+</sup> | (index: number) => [number, number,number,number] | 否 | 设置指定索引index对应的GridItem的位置及大小[rowStart,columnStart,rowSpan,columnSpan]。 <br/>其中rowStart为行起始位置,columnStart为列起始位置,无单位。 <br/>rowSpan为GridItem占用的行数,columnSpan为GridItem占用的列数,无单位。 <br/>rowStart和columnStart取大于等于0的自然数,若取负数时,rowStart和columnStart默认为0。 <br/>rowSpan和columnSpan取大于等于1的自然数,若取小数则向下取整,若小于1则按1计算。<br/>**说明:** <br/>第一种情况:某个GridItem发现给它指定的起始位置被占据了,则从起始位置[0,0]开始按顺序从左到右,从上到下寻找起始的放置位置。<br/>第二种情况:如果起始位置没有被占据,但其他位置被占据了,无法显示全部的GridItem大小,则只会布局一部分。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 63 64## 属性 65 66除支持[通用属性](ts-universal-attributes-size.md)和[滚动组件通用属性](ts-container-scrollable-common.md#属性)外,还支持以下属性: 67 68### columnsTemplate 69 70columnsTemplate(value: string) 71 72设置当前网格布局列的数量、固定列宽或最小列宽值,不设置时默认1列。 73 74例如, '1fr 1fr 2fr' 是将父组件分3列,将父组件允许的宽分为4等份,第一列占1份,第二列占1份,第三列占2份。 75 76columnsTemplate('repeat(auto-fit, track-size)')是设置最小列宽值为track-size,自动计算列数和实际列宽。 77 78columnsTemplate('repeat(auto-fill, track-size)')是设置固定列宽值为track-size,自动计算列数。 79 80columnsTemplate('repeat(auto-stretch, track-size)')是设置固定列宽值为track-size,使用columnsGap为最小列间距,自动计算列数和实际列间距。 81 82其中repeat、auto-fit、auto-fill、auto-stretch为关键字。track-size为列宽,支持的单位包括px、vp、%或有效数字,默认单位为vp,track-size至少包括一个有效列宽。<br/> 83auto-stretch模式只支持track-size为一个有效列宽值,并且track-size只支持px、vp和有效数字,不支持%。 84 85使用效果可以参考示[示例8](#示例8设置自适应列数)。 86 87设置为'0fr'时,该列的列宽为0,不显示GridItem。设置为其他非法值时,GridItem显示为固定1列。 88 89**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 90 91**系统能力:** SystemCapability.ArkUI.ArkUI.Full 92 93**参数:** 94 95| 参数名 | 类型 | 必填 | 说明 | 96| ------ | ------ | ---- | ---------------------------------- | 97| value | string | 是 | 当前网格布局列的数量或最小列宽值。 | 98 99### rowsTemplate 100 101rowsTemplate(value: string) 102 103设置当前网格布局行的数量、固定行高或最小行高值,不设置时默认1行。 104 105例如, '1fr 1fr 2fr'是将父组件分3行,将父组件允许的高分为4等份,第一行占1份,第二行占一份,第三行占2份。 106 107rowsTemplate('repeat(auto-fit, track-size)')是设置最小行高值为track-size,自动计算行数和实际行高。 108 109rowsTemplate('repeat(auto-fill, track-size)')是设置固定行高值为track-size,自动计算行数。 110 111rowsTemplate('repeat(auto-stretch, track-size)')是设置固定行高值为track-size,使用rowsGap为最小行间距,自动计算行数和实际行间距。 112 113其中repeat、auto-fit、auto-fill、auto-stretch为关键字。track-size为行高,支持的单位包括px、vp、%或有效数字,默认单位为vp,track-size至少包括一个有效行高。<br/> 114auto-stretch模式只支持track-size为一个有效行高值,并且track-size只支持px、vp和有效数字,不支持%。 115 116设置为'0fr',则这一行的行宽为0,这一行GridItem不显示。设置为其他非法值,按固定1行处理。 117 118**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 119 120**系统能力:** SystemCapability.ArkUI.ArkUI.Full 121 122**参数:** 123 124| 参数名 | 类型 | 必填 | 说明 | 125| ------ | ------ | ---- | ---------------------------------- | 126| value | string | 是 | 当前网格布局行的数量或最小行高值。 | 127 128> **说明:** 129> 130> Grid组件根据rowsTemplate、columnsTemplate属性的设置情况,可分为以下三种布局模式: 131> 132> 1、rowsTemplate、columnsTemplate同时设置: 133> 134> - Grid只展示固定行列数的元素,其余元素不展示,且Grid不可滚动。 135> - 此模式下以下属性不生效:layoutDirection、maxCount、minCount、cellLength。 136> - Grid的宽高没有设置时,默认适应父组件尺寸。 137> - Grid网格列大小按照Grid自身内容区域大小减去所有行列Gap后按各个行列所占比重分配。 138> - GridItem默认填满网格大小。 139> 140> 2、rowsTemplate、columnsTemplate仅设置其中的一个: 141> 142> - 元素按照设置的方向进行排布,超出Grid显示区域后,Grid可通过滚动的方式展示。 143> - 如果设置了columnsTemplate,Grid滚动方向为垂直方向,主轴方向为垂直方向,交叉轴方向为水平方向。 144> - 如果设置了rowsTemplate,Grid滚动方向为水平方向,主轴方向为水平方向,交叉轴方向为垂直方向。 145> - 此模式下以下属性不生效:layoutDirection、maxCount、minCount、cellLength。 146> - 网格交叉轴方向尺寸根据Grid自身内容区域交叉轴尺寸减去交叉轴方向所有Gap后按所占比重分配。 147> - 网格主轴方向尺寸取当前网格交叉轴方向所有GridItem主轴方向尺寸最大值。 148> 149> 3、rowsTemplate、columnsTemplate都不设置: 150> 151> - 元素在layoutDirection方向上排布,列数由Grid的宽度、首个元素的宽度、minCount、maxCount、columnsGap共同决定。 152> - 行数由Grid高度、首个元素高度、cellLength、rowsGap共同决定。超出行列容纳范围的元素不显示,也不能通过滚动进行展示。 153> - 此模式下仅生效以下属性:layoutDirection、maxCount、minCount、cellLength、editMode、columnsGap、rowsGap。 154> - 当前layoutDirection设置为Row时,先从左到右排列,排满一行再排下一行。剩余高度不足时不再布局,整体内容顶部居中。 155> - 当前layoutDirection设置为Column时,先从上到下排列,排满一列再排下一列,剩余宽度不足时不再布局。整体内容顶部居中。 156> - 当前Grid下面没有GridItem时,Grid的宽高为0。 157> 158 159### columnsGap 160 161columnsGap(value: Length) 162 163设置列与列的间距。设置为小于0的值时,按默认值显示。 164 165**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 166 167**系统能力:** SystemCapability.ArkUI.ArkUI.Full 168 169**参数:** 170 171| 参数名 | 类型 | 必填 | 说明 | 172| ------ | ---------------------------- | ---- | ---------------------------- | 173| value | [Length](ts-types.md#length) | 是 | 列与列的间距。<br/>默认值:0 | 174 175### rowsGap 176 177rowsGap(value: Length) 178 179设置行与行的间距。设置为小于0的值时,按默认值显示。 180 181**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 182 183**系统能力:** SystemCapability.ArkUI.ArkUI.Full 184 185**参数:** 186 187| 参数名 | 类型 | 必填 | 说明 | 188| ------ | ---------------------------- | ---- | ---------------------------- | 189| value | [Length](ts-types.md#length) | 是 | 行与行的间距。<br/>默认值:0 | 190 191### scrollBar 192 193scrollBar(value: BarState) 194 195设置滚动条状态。 196 197**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 198 199**系统能力:** SystemCapability.ArkUI.ArkUI.Full 200 201**参数:** 202 203| 参数名 | 类型 | 必填 | 说明 | 204| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ | 205| value | [BarState](ts-appendix-enums.md#barstate) | 是 | 滚动条状态。<br/>默认值:BarState.Auto<br/>**说明:** <br/>API version 9及以下版本默认值为BarState.Off,API version 10及以上版本的默认值为BarState.Auto。 | 206 207### scrollBarColor 208 209scrollBarColor(value: Color | number | string) 210 211设置滚动条的颜色。 212 213**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 214 215**系统能力:** SystemCapability.ArkUI.ArkUI.Full 216 217**参数:** 218 219| 参数名 | 类型 | 必填 | 说明 | 220| ------ | ------------------------------------------------------------ | ---- | -------------- | 221| value | [Color](ts-appendix-enums.md#color) \| number \| string | 是 | 滚动条的颜色。<br/>默认值:'\#182431'(40%不透明度) | 222 223### scrollBarWidth 224 225scrollBarWidth(value: number | string) 226 227设置滚动条的宽度,不支持百分比设置。宽度设置后,滚动条正常状态和按压状态宽度均为滚动条的宽度值。如果滚动条的宽度超过Grid组件主轴方向的高度,则滚动条的宽度会变为默认值。 228 229**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 230 231**系统能力:** SystemCapability.ArkUI.ArkUI.Full 232 233**参数:** 234 235| 参数名 | 类型 | 必填 | 说明 | 236| ------ | -------------------------- | ---- | ----------------------------------------- | 237| value | number \| string | 是 | 滚动条的宽度。<br/>默认值:4<br/>单位:vp | 238 239### cachedCount 240 241cachedCount(value: number) 242 243设置预加载的GridItem的数量,只在[LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md)和开启了virtualScroll开关的[Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md)中生效。设置为小于0的值时,按默认值显示。<!--Del-->具体使用可参考[减少应用白块说明](../../../performance/arkts-performance-improvement-recommendation.md#减少应用滑动白块)。<!--DelEnd--> 244 245设置缓存后会在Grid显示区域上下各缓存cachedCount*列数个GridItem。 246 247[LazyForEach](../../../quick-start/arkts-rendering-control-lazyforeach.md)和开启了virtualScroll开关的[Repeat](../../../quick-start/arkts-new-rendering-control-repeat.md)超出显示和缓存范围的GridItem会被释放。 248 249**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 250 251**系统能力:** SystemCapability.ArkUI.ArkUI.Full 252 253**参数:** 254 255| 参数名 | 类型 | 必填 | 说明 | 256| ------ | ------ | ---- | ------------------------------------------------------------ | 257| value | number | 是 | 预加载的GridItem的数量。<br/>默认值:垂直滚动时为一个屏幕内可显示的行数,水平滚动时为一个屏幕内可显示的列数,最大值为16。 | 258 259### cachedCount<sup>14+</sup> 260 261cachedCount(count: number, show: boolean) 262 263设置预加载的GridItem数量,并配置是否显示预加载节点。 264 265设置缓存后会在Grid显示区域上下各缓存cachedCount*列数个GridItem。配合[裁剪](ts-universal-attributes-sharp-clipping.md#clip12)或[内容裁剪](ts-container-scrollable-common.md#clipcontent14)属性可以显示出预加载节点。 266 267**原子化服务API:** 从API version 14开始,该接口支持在原子化服务中使用。 268 269**系统能力:** SystemCapability.ArkUI.ArkUI.Full 270 271**参数:** 272 273| 参数名 | 类型 | 必填 | 说明 | 274| ------ | ------ | ---- | -------------------------------------- | 275| count | number | 是 | 预加载的GridItem的数量。<br/>默认值:垂直滚动时为一个屏幕内可显示的行数,水平滚动时为一个屏幕内可显示的列数,最大值为16。 | 276| show | boolean | 是 | 被预加载的GridItem是否需要显示。 <br/> 默认值:false | 277 278### editMode<sup>8+</sup> 279 280editMode(value: boolean) 281 282设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部[GridItem](ts-container-griditem.md)。 283 284**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 285 286**系统能力:** SystemCapability.ArkUI.ArkUI.Full 287 288**参数:** 289 290| 参数名 | 类型 | 必填 | 说明 | 291| ------ | ------ | ---- | ---------------------------------------- | 292| value | boolean | 是 | Grid是否进入编辑模式。<br/>默认值:false | 293 294### layoutDirection<sup>8+</sup> 295 296layoutDirection(value: GridDirection) 297 298设置布局的主轴方向。 299 300**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 301 302**系统能力:** SystemCapability.ArkUI.ArkUI.Full 303 304**参数:** 305 306| 参数名 | 类型 | 必填 | 说明 | 307| ------ | ---------------------------------------- | ---- | ---------------------------------------------- | 308| value | [GridDirection](#griddirection8枚举说明) | 是 | 布局的主轴方向。<br/>默认值:GridDirection.Row | 309 310### maxCount<sup>8+</sup> 311 312maxCount(value: number) 313 314设置可显示的最大行数或列数。设置为小于1的值时,按默认值显示。 315 316当layoutDirection是Row/RowReverse时,表示可显示的最大列数。 317 318当layoutDirection是Column/ColumnReverse时,表示可显示的最大行数。 319 320当maxCount小于minCount时,maxCount和minCount都按默认值处理。 321 322**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 323 324**系统能力:** SystemCapability.ArkUI.ArkUI.Full 325 326**参数:** 327 328| 参数名 | 类型 | 必填 | 说明 | 329| ------ | ------ | ---- | --------------------------------------------- | 330| value | number | 是 | 可显示的最大行数或列数。<br/>默认值:Infinity | 331 332### minCount<sup>8+</sup> 333 334minCount(value: number) 335 336设置可显示的最小行数或列数。设置为小于1的值时,按默认值显示。 337 338当layoutDirection是Row/RowReverse时,表示可显示的最小列数。 339 340当layoutDirection是Column/ColumnReverse时,表示可显示的最小行数。 341 342**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 343 344**系统能力:** SystemCapability.ArkUI.ArkUI.Full 345 346**参数:** 347 348| 参数名 | 类型 | 必填 | 说明 | 349| ------ | ------ | ---- | -------------------------------------- | 350| value | number | 是 | 可显示的最小行数或列数。<br/>默认值:1 | 351 352### cellLength<sup>8+</sup> 353 354cellLength(value: number) 355 356设置一行的高度或者一列的宽度。 357 358当layoutDirection是Row/RowReverse时,表示一行的高度。 359 360当layoutDirection是Column/ColumnReverse时,表示一列的宽度。 361 362**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 363 364**系统能力:** SystemCapability.ArkUI.ArkUI.Full 365 366**参数:** 367 368| 参数名 | 类型 | 必填 | 说明 | 369| ------ | ------ | ---- | ------------------------------------------------------- | 370| value | number | 是 | 一行的高度或者一列的宽度。<br/>默认值:第一个元素的大小 <br/>单位:vp| 371 372### multiSelectable<sup>8+</sup> 373 374multiSelectable(value: boolean) 375 376设置是否开启鼠标框选。开启框选后,可以配合Griditem的selected属性和onSelect事件获取GridItem的选中状态,还可以设置[选中态样式](./ts-universal-attributes-polymorphic-style.md)(无默认选中样式)。 377 378**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 379 380**系统能力:** SystemCapability.ArkUI.ArkUI.Full 381 382**参数:** 383 384| 参数名 | 类型 | 必填 | 说明 | 385| ------ | ------- | ---- | ------------------------------------------------------------ | 386| value | boolean | 是 | 是否开启鼠标框选。<br/>默认值:false<br/>false:关闭框选。true:开启框选。 | 387 388### supportAnimation<sup>8+</sup> 389 390supportAnimation(value: boolean) 391 392设置是否支持动画。当前支持GridItem拖拽动画。仅在滚动模式下(只设置rowsTemplate、columnsTemplate其中一个)支持动画。<br/>仅在大小规则的Grid中支持拖拽动画,跨行或跨列场景不支持。 393 394**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 395 396**系统能力:** SystemCapability.ArkUI.ArkUI.Full 397 398**参数:** 399 400| 参数名 | 类型 | 必填 | 说明 | 401| ------ | ------- | ---- | -------------------------------- | 402| value | boolean | 是 | 是否支持动画。<br/>默认值:false | 403 404### edgeEffect<sup>10+</sup> 405 406edgeEffect(value: EdgeEffect, options?: EdgeEffectOptions) 407 408设置边缘滑动效果。 409 410**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 411 412**系统能力:** SystemCapability.ArkUI.ArkUI.Full 413 414**参数:** 415 416| 参数名 | 类型 | 必填 | 说明 | 417| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 418| value | [EdgeEffect](ts-appendix-enums.md#edgeeffect) | 是 | Grid组件的边缘滑动效果,支持弹簧效果和阴影效果。<br/>默认值:EdgeEffect.None | 419| options<sup>11+</sup> | [EdgeEffectOptions](ts-container-scrollable-common.md#edgeeffectoptions11对象说明) | 否 | 组件内容大小小于组件自身时,是否开启滑动效果。设置为{ alwaysEnabled: true }会开启滑动效果,{ alwaysEnabled: false }不开启。<br/>默认值:{ alwaysEnabled: false } | 420 421### enableScrollInteraction<sup>10+</sup> 422 423enableScrollInteraction(value: boolean) 424 425设置是否支持滚动手势,当设置为false时,无法通过手指或者鼠标滚动,但不影响控制器的滚动接口。 426 427**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 428 429**系统能力:** SystemCapability.ArkUI.ArkUI.Full 430 431**参数:** 432 433| 参数名 | 类型 | 必填 | 说明 | 434| ------ | ------- | ---- | ----------------------------------- | 435| value | boolean | 是 | 是否支持滚动手势。<br/>默认值:true | 436 437### nestedScroll<sup>10+</sup> 438 439nestedScroll(value: NestedScrollOptions) 440 441设置嵌套滚动选项。设置向前向后两个方向上的嵌套滚动模式,实现与父组件的滚动联动。 442 443**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 444 445**系统能力:** SystemCapability.ArkUI.ArkUI.Full 446 447**参数:** 448 449| 参数名 | 类型 | 必填 | 说明 | 450| ------ | ------------------------------------------------------------ | ---- | -------------- | 451| value | [NestedScrollOptions](ts-container-scrollable-common.md#nestedscrolloptions10对象说明) | 是 | 嵌套滚动选项。 | 452 453### friction<sup>10+</sup> 454 455friction(value: number | Resource) 456 457设置摩擦系数,手动划动滚动区域时生效,只对惯性滚动过程有影响,对惯性滚动过程中的链式效果有间接影响。设置为小于等于0的值时,按默认值处理 458 459**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 460 461**系统能力:** SystemCapability.ArkUI.ArkUI.Full 462 463**参数:** 464 465| 参数名 | 类型 | 必填 | 说明 | 466| ------ | ---------------------------------------------------- | ---- | ----------------------------------------------------------- | 467| value | number \| [Resource](ts-types.md#resource) | 是 | 摩擦系数。<br/>默认值:非可穿戴设备为0.6,可穿戴设备为0.9。<br/>从API version 11开始,非可穿戴设备默认值为0.7。<br/>从API version 12开始,非可穿戴设备默认值为0.75。 | 468 469### alignItems<sup>12+</sup> 470 471alignItems(alignment: Optional\<GridItemAlignment\>) 472 473设置Grid中GridItem的对齐方式, 使用方法可以参考[示例9](#示例9以当前行最高的griditem的高度为其他griditem的高度)。 474 475**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 476 477**系统能力:** SystemCapability.ArkUI.ArkUI.Full 478 479**参数:** 480 481| 参数名 | 类型 | 必填 | 说明 | 482| ---------- | ------ | ---- | ------------------------------- | 483| alignment | Optional\<[GridItemAlignment](#griditemalignment12枚举说明)\> | 是 | 设置Grid中GridItem的对齐方式。<br/>默认值:GridItemAlignment.DEFAULT | 484 485## GridItemAlignment<sup>12+</sup>枚举说明 486 487**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 488 489**系统能力:** SystemCapability.ArkUI.ArkUI.Full 490 491| 名称 | 值 | 说明 | 492| ------ |------| -------------------------------------- | 493| DEFAULT | 0 | 使用Grid的默认对齐方式。 | 494| STRETCH | 1 | 以一行中的最高的GridItem作为其他GridItem的高度。 | 495 496 497> **说明:** 498> 499> 1、只有可滚动的Grid中,设置STRETCH参数会生效,其他场景不生效。<br/> 500> 2、在Grid的一行中,如果每个GridItem都是大小规律的(只占一行一列),设置STRETCH参数会生效,存在跨行或跨列的GridItem的场景不生效。<br/> 501> 3、设置STRETCH后,只有不设置高度的GridItem才会以当前行中最高的GridItem作为自己的高度,设置过高度的GridItem高度不会变化。<br/> 502> 4、设置STRETCH后,Grid布局时会有额外的布局流程,可能会带来额外的性能开销。 503 504## GridDirection<sup>8+</sup>枚举说明 505 506**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 507 508**系统能力:** SystemCapability.ArkUI.ArkUI.Full 509 510| 名称 |值| 说明 | 511| ------ |------| -------------------------------------- | 512| Row | 0 | 主轴布局方向沿水平方向布局,即自左往右先填满一行,再去填下一行。 | 513| Column | 1 | 主轴布局方向沿垂直方向布局,即自上往下先填满一列,再去填下一列。 | 514| RowReverse | 2 | 主轴布局方向沿水平方向反向布局,即自右往左先填满一行,再去填下一行。 | 515| ColumnReverse | 3 | 主轴布局方向沿垂直方向反向布局,即自下往上先填满一列,再去填下一列。 | 516 517> **说明:** 518> 519> Grid组件[通用属性clip](ts-universal-attributes-sharp-clipping.md)的默认值为true。 520 521## 事件 522 523除支持[通用事件](ts-universal-events-click.md)和[滚动组件通用事件](ts-container-scrollable-common.md#事件)外,还支持以下事件: 524 525### onScrollIndex 526 527onScrollIndex(event: (first: number, last: number) => void) 528 529当前网格显示的起始位置/终止位置的item发生变化时触发。网格初始化时会触发一次。Grid显示区域上第一个子组件/最后一个组件的索引值有变化就会触发。 530 531**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 532 533**系统能力:** SystemCapability.ArkUI.ArkUI.Full 534 535**参数:** 536 537| 参数名 | 类型 | 必填 | 说明 | 538| ------------------ | ------ | ---- | -------------------------------- | 539| first | number | 是 | 当前显示的网格起始位置的索引值。 | 540| last<sup>10+</sup> | number | 是 | 当前显示的网格终止位置的索引值。 | 541 542### onItemDragStart<sup>8+</sup> 543 544onItemDragStart(event: (event: ItemDragInfo, itemIndex: number) => (() => any) \| void) 545 546开始拖拽网格元素时触发。返回void表示不能拖拽。 547 548手指长按GridItem时触发该事件。 549 550由于拖拽检测也需要长按,且事件处理机制优先触发子组件事件,GridItem上绑定LongPressGesture时无法触发拖拽。如有长按和拖拽同时使用的需求可以使用通用拖拽事件。 551 552**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 553 554**系统能力:** SystemCapability.ArkUI.ArkUI.Full 555 556**参数:** 557 558| 参数名 | 类型 | 必填 | 说明 | 559| --------- | ------------------------------------- | ---- | ---------------------- | 560| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo对象说明) | 是 | 拖拽点的信息。 | 561| itemIndex | number | 是 | 被拖拽网格元素索引值。 | 562 563### onItemDragEnter<sup>8+</sup> 564 565onItemDragEnter(event: (event: ItemDragInfo) => void) 566 567拖拽进入网格元素范围内时触发。 568 569**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 570 571**系统能力:** SystemCapability.ArkUI.ArkUI.Full 572 573**参数:** 574 575| 参数名 | 类型 | 必填 | 说明 | 576| ------ | ------------------------------------- | ---- | -------------- | 577| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo对象说明) | 是 | 拖拽点的信息。 | 578 579### onItemDragMove<sup>8+</sup> 580 581onItemDragMove(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number) => void) 582 583拖拽在网格元素范围内移动时触发。 584 585**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 586 587**系统能力:** SystemCapability.ArkUI.ArkUI.Full 588 589**参数:** 590 591| 参数名 | 类型 | 必填 | 说明 | 592| ----------- | ------------------------------------- | ---- | -------------- | 593| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo对象说明) | 是 | 拖拽点的信息。 | 594| itemIndex | number | 是 | 拖拽起始位置。 | 595| insertIndex | number | 是 | 拖拽插入位置。 | 596 597### onItemDragLeave<sup>8+</sup> 598 599onItemDragLeave(event: (event: ItemDragInfo, itemIndex: number) => void) 600 601拖拽离开网格元素时触发。 602 603**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 604 605**系统能力:** SystemCapability.ArkUI.ArkUI.Full 606 607**参数:** 608 609| 参数名 | 类型 | 必填 | 说明 | 610| --------- | ------------------------------------- | ---- | -------------------------- | 611| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo对象说明) | 是 | 拖拽点的信息。 | 612| itemIndex | number | 是 | 拖拽离开的网格元素索引值。 | 613 614### onItemDrop<sup>8+</sup> 615 616onItemDrop(event: (event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => void) 617 618绑定该事件的网格元素可作为拖拽释放目标,当在网格元素内停止拖拽时触发。 619 620**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 621 622**系统能力:** SystemCapability.ArkUI.ArkUI.Full 623 624**参数:** 625 626| 参数名 | 类型 | 必填 | 说明 | 627| ----------- | ------------------------------------- | ---- | -------------- | 628| event | [ItemDragInfo](ts-container-scrollable-common.md#itemdraginfo对象说明) | 是 | 拖拽点的信息。 | 629| itemIndex | number | 是 | 拖拽起始位置。 | 630| insertIndex | number | 是 | 拖拽插入位置。 | 631| isSuccess | boolean | 是 | 是否成功释放 | 632 633### onScrollBarUpdate<sup>10+</sup> 634 635onScrollBarUpdate(event: (index: number, offset: number) => ComputedBarAttribute) 636 637当前网格显示的起始位置item发生变化时触发,可通过该回调设置滚动条的位置及长度。 638 639该接口只用作设置Grid的滚动条位置,不建议开发者在此接口中做业务逻辑处理。 640 641**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 642 643**系统能力:** SystemCapability.ArkUI.ArkUI.Full 644 645**参数:** 646 647| 参数名 | 类型 | 必填 | 说明 | 648| ------ | ------ | ---- | ------------------------------------------------------------ | 649| index | number | 是 | 当前显示的网格起始位置的索引值。 | 650| offset | number | 是 | 当前显示的网格起始位置元素相对网格显示起始位置的偏移,单位vp。 | 651 652**返回值:** 653 654| 类型 | 说明 | 655| ----------------------------------------------------- | -------------------- | 656| [ComputedBarAttribute](#computedbarattribute10对象说明) | 滚动条的位置及长度。 | 657 658### onReachStart<sup>10+</sup> 659 660onReachStart(event: () => void) 661 662网格到达起始位置时触发。 663 664Grid初始化时会触发一次,Grid滚动到起始位置时触发一次。Grid边缘效果为弹簧效果时,划动经过起始位置时触发一次,回弹回起始位置时再触发一次。 665 666**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 667 668**系统能力:** SystemCapability.ArkUI.ArkUI.Full 669 670### onReachEnd<sup>10+</sup> 671 672onReachEnd(event: () => void) 673 674网格到达末尾位置时触发。 675 676Grid边缘效果为弹簧效果时,划动经过末尾位置时触发一次,回弹回末尾位置时再触发一次。 677 678**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 679 680**系统能力:** SystemCapability.ArkUI.ArkUI.Full 681 682### onScrollFrameBegin<sup>10+</sup> 683 684onScrollFrameBegin(event: (offset: number, state: ScrollState) => { offsetRemain: number }) 685 686网格开始滑动时触发,事件参数传入即将发生的滑动量,事件处理函数中可根据应用场景计算实际需要的滑动量并作为事件处理函数的返回值返回,网格将按照返回值的实际滑动量进行滑动。 687 688**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 689 690**系统能力:** SystemCapability.ArkUI.ArkUI.Full 691 692**参数:** 693 694| 参数名 | 类型 | 必填 | 说明 | 695| ------ | ------------------------------------------------------- | ---- | -------------------------- | 696| offset | number | 是 | 即将发生的滑动量,单位vp。 | 697| state | [ScrollState](ts-container-list.md#scrollstate枚举说明) | 是 | 当前滑动状态。 | 698 699**返回值:** 700 701| 类型 | 说明 | 702| ------------------------ | -------------------- | 703| { offsetRemain: number } | 实际滑动量,单位vp。 | 704 705### onScrollStart<sup>10+</sup> 706 707onScrollStart(event: () => void) 708 709网格滑动开始时触发。手指拖动网格或网格的滚动条触发的滑动开始时,会触发该事件。使用[Scroller](ts-container-scroll.md#scroller)滑动控制器触发的带动画的滑动,动画开始时会触发该事件。 710 711**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 712 713**系统能力:** SystemCapability.ArkUI.ArkUI.Full 714 715### onScrollStop<sup>10+</sup> 716 717onScrollStop(event: () => void) 718 719网格滑动停止时触发。手指拖动网格或网格的滚动条触发的滑动,手指离开屏幕并且滑动停止时会触发该事件。使用[Scroller](ts-container-scroll.md#scroller)滑动控制器触发的带动画的滑动,动画停止会触发该事件。 720 721**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 722 723**系统能力:** SystemCapability.ArkUI.ArkUI.Full 724 725### onScroll<sup>(deprecated)</sup> 726onScroll(event: (scrollOffset: number, scrollState: [ScrollState](ts-container-list.md#scrollstate枚举说明)) => void) 727 728网格滑动时触发。 729 730从API version 10开始使用。 731 732从API version 12开始废弃不再使用,建议使用[onDidScroll](ts-container-scrollable-common.md#ondidscroll12)替代。 733 734**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 735 736**系统能力:** SystemCapability.ArkUI.ArkUI.Full 737 738**参数:** 739 740| 参数名 | 类型 | 必填 | 说明 | 741| ------ | ------ | ------ | ------| 742| scrollOffset | number | 是 | 每帧滚动的偏移量,Grid的内容向上滚动时偏移量为正,向下滚动时偏移量为负。<br/>单位vp。 | 743| scrollState | [ScrollState](ts-container-list.md#scrollstate枚举说明) | 是 | 当前滑动状态。 | 744 745## ComputedBarAttribute<sup>10+</sup>对象说明 746 747**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 748 749**系统能力:** SystemCapability.ArkUI.ArkUI.Full 750 751| 名称 | 类型 | 只读 | 可选 | 说明 | 752| ----------- | ------------ | ---- | ---- | ---------- | 753| totalOffset | number | 否 | 否 | Grid内容相对显示区域的总偏移,单位px。 | 754| totalLength | number | 否 | 否 | Grid内容总长度,单位px。 | 755 756## 示例 757 758### 示例1(固定行列Grid) 759 760可以使用GridLayoutOptions中的onGetRectByIndex指定GridItem的位置和大小。 761 762```ts 763// xxx.ets 764@Entry 765@Component 766struct GridExample { 767 @State numbers1: String[] = ['0', '1', '2', '3', '4'] 768 @State numbers2: String[] = ['0', '1','2','3','4','5'] 769 770 layoutOptions3: GridLayoutOptions = { 771 regularSize: [1, 1], 772 onGetRectByIndex: (index: number) => { 773 if (index == 0) 774 return [0, 0, 1, 1] 775 else if(index==1) 776 return [0, 1, 2, 2] 777 else if(index==2) 778 return [0 ,3 ,3 ,3] 779 else if(index==3) 780 return [3, 0, 3, 3] 781 else if(index==4) 782 return [4, 3, 2, 2] 783 else 784 return [5, 5, 1, 1] 785 } 786 } 787 788 build() { 789 Column({ space: 5 }) { 790 Grid() { 791 ForEach(this.numbers1, (day: string) => { 792 ForEach(this.numbers1, (day: string) => { 793 GridItem() { 794 Text(day) 795 .fontSize(16) 796 .backgroundColor(0xF9CF93) 797 .width('100%') 798 .height('100%') 799 .textAlign(TextAlign.Center) 800 } 801 }, (day: string) => day) 802 }, (day: string) => day) 803 } 804 .columnsTemplate('1fr 1fr 1fr 1fr 1fr') 805 .rowsTemplate('1fr 1fr 1fr 1fr 1fr') 806 .columnsGap(10) 807 .rowsGap(10) 808 .width('90%') 809 .backgroundColor(0xFAEEE0) 810 .height(300) 811 812 Text('GridLayoutOptions的使用:onGetRectByIndex。').fontColor(0xCCCCCC).fontSize(9).width('90%') 813 814 Grid(undefined, this.layoutOptions3) { 815 ForEach(this.numbers2, (day: string) => { 816 GridItem() { 817 Text(day) 818 .fontSize(16) 819 .backgroundColor(0xF9CF93) 820 .width('100%') 821 .height("100%") 822 .textAlign(TextAlign.Center) 823 } 824 .height("100%") 825 .width('100%') 826 }, (day: string) => day) 827 } 828 .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr') 829 .rowsTemplate('1fr 1fr 1fr 1fr 1fr 1fr') 830 .columnsGap(10) 831 .rowsGap(10) 832 .width('90%') 833 .backgroundColor(0xFAEEE0) 834 .height(300) 835 }.width('100%').margin({ top: 5 }) 836 } 837} 838``` 839 840 841 842### 示例2(可滚动Grid和滚动事件) 843 844可滚动Grid,包括所有滚动属性和事件。 845 846```ts 847// xxx.ets 848@Entry 849@Component 850struct GridExample { 851 @State numbers: String[] = ['0', '1', '2', '3', '4'] 852 scroller: Scroller = new Scroller() 853 @State gridPosition: number = 0 //0代表滚动到grid顶部,1代表中间值,2代表滚动到grid底部。 854 855 build() { 856 Column({ space: 5 }) { 857 Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%') 858 Grid(this.scroller) { 859 ForEach(this.numbers, (day: string) => { 860 ForEach(this.numbers, (day: string) => { 861 GridItem() { 862 Text(day) 863 .fontSize(16) 864 .backgroundColor(0xF9CF93) 865 .width('100%') 866 .height(80) 867 .textAlign(TextAlign.Center) 868 } 869 }, (day: string) => day) 870 }, (day: string) => day) 871 } 872 .columnsTemplate('1fr 1fr 1fr 1fr 1fr') 873 .columnsGap(10) 874 .rowsGap(10) 875 .friction(0.6) 876 .enableScrollInteraction(true) 877 .supportAnimation(false) 878 .multiSelectable(false) 879 .edgeEffect(EdgeEffect.Spring) 880 .scrollBar(BarState.On) 881 .scrollBarColor(Color.Grey) 882 .scrollBarWidth(4) 883 .width('90%') 884 .backgroundColor(0xFAEEE0) 885 .height(300) 886 .onScrollIndex((first: number, last: number) => { 887 console.info(first.toString()) 888 console.info(last.toString()) 889 }) 890 .onScrollBarUpdate((index: number, offset: number) => { 891 console.info("XXX" + 'Grid onScrollBarUpdate,index : ' + index.toString() + ",offset" + offset.toString()) 892 return { totalOffset: (index / 5) * (80 + 10) - offset, totalLength: 80 * 5 + 10 * 4 } 893 }) //只适用于当前示例代码数据源,如果数据源有变化,则需要修改该部分代码,或者删掉此属性 894 .onDidScroll((scrollOffset: number, scrollState: ScrollState) => { 895 console.info(scrollOffset.toString()) 896 console.info(scrollState.toString()) 897 }) 898 .onScrollStart(() => { 899 console.info("XXX" + "Grid onScrollStart") 900 }) 901 .onScrollStop(() => { 902 console.info("XXX" + "Grid onScrollStop") 903 }) 904 .onReachStart(() => { 905 this.gridPosition = 0 906 console.info("XXX" + "Grid onReachStart") 907 }) 908 .onReachEnd(() => { 909 this.gridPosition = 2 910 console.info("XXX" + "Grid onReachEnd") 911 }) 912 913 Button('next page') 914 .onClick(() => { // 点击后滑到下一页 915 this.scroller.scrollPage({ next: true }) 916 }) 917 }.width('100%').margin({ top: 5 }) 918 } 919} 920``` 921 922 923 924### 示例3(可滚动Grid设置跨行跨列节点) 925 926GridLayoutOptions的使用:irregularIndexes与onGetIrregularSizeByIndex。 927 928```ts 929// xxx.ets 930@Entry 931@Component 932struct GridExample { 933 @State numbers: String[] = ['0', '1', '2', '3', '4'] 934 scroller: Scroller = new Scroller() 935 layoutOptions1: GridLayoutOptions = { 936 regularSize: [1, 1], // 只支持[1, 1] 937 irregularIndexes: [0, 6], // 索引为0和6的GridItem占用一行 938 } 939 940 layoutOptions2: GridLayoutOptions = { 941 regularSize: [1, 1], 942 irregularIndexes: [0, 7], // 索引为0和7的GridItem占用的列数由onGetIrregularSizeByIndex指定 943 onGetIrregularSizeByIndex: (index: number) => { 944 if (index === 0) { 945 return [1, 5] 946 } 947 return [1, index % 6 + 1] 948 } 949 } 950 951 build() { 952 Column({ space: 5 }) { 953 Grid(this.scroller, this.layoutOptions1) { 954 ForEach(this.numbers, (day: string) => { 955 ForEach(this.numbers, (day: string) => { 956 GridItem() { 957 Text(day) 958 .fontSize(16) 959 .backgroundColor(0xF9CF93) 960 .width('100%') 961 .height(80) 962 .textAlign(TextAlign.Center) 963 }.selectable(false) 964 }, (day: string) => day) 965 }, (day: string) => day) 966 } 967 .columnsTemplate('1fr 1fr 1fr 1fr 1fr') 968 .columnsGap(10) 969 .rowsGap(10) 970 .multiSelectable(true) 971 .scrollBar(BarState.Off) 972 .width('90%') 973 .backgroundColor(0xFAEEE0) 974 .height(300) 975 976 Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%') 977 // 不使用scroll,需要undefined占位 978 Grid(undefined, this.layoutOptions2) { 979 ForEach(this.numbers, (day: string) => { 980 ForEach(this.numbers, (day: string) => { 981 GridItem() { 982 Text(day) 983 .fontSize(16) 984 .backgroundColor(0xF9CF93) 985 .width('100%') 986 .height(80) 987 .textAlign(TextAlign.Center) 988 } 989 }, (day: string) => day) 990 }, (day: string) => day) 991 } 992 .columnsTemplate('1fr 1fr 1fr 1fr 1fr') 993 .columnsGap(10) 994 .rowsGap(10) 995 .scrollBar(BarState.Off) 996 .width('90%') 997 .backgroundColor(0xFAEEE0) 998 .height(300) 999 }.width('100%').margin({ top: 5 }) 1000 } 1001} 1002``` 1003 1004 1005 1006### 示例4(Grid嵌套滚动) 1007 1008nestedScroll和onScrollFrameBegin的使用。 1009 1010```ts 1011@Entry 1012@Component 1013struct GridExample { 1014 @State colors: number[] = [0xFFC0CB, 0xDA70D6, 0x6B8E23, 0x6A5ACD, 0x00FFFF, 0x00FF7F] 1015 @State numbers: number[] = [] 1016 @State translateY: number = 0 1017 private scroller: Scroller = new Scroller() 1018 private gridScroller: Scroller = new Scroller() 1019 private touchDown: boolean = false 1020 private listTouchDown: boolean = false 1021 private scrolling: boolean = false 1022 1023 aboutToAppear() { 1024 for (let i = 0; i < 100; i++) { 1025 this.numbers.push(i) 1026 } 1027 } 1028 1029 build() { 1030 Stack() { 1031 Column() { 1032 Row() { 1033 Text('Head') 1034 } 1035 1036 Column() { 1037 List({ scroller: this.scroller }) { 1038 ListItem() { 1039 Grid() { 1040 GridItem() { 1041 Text('GoodsTypeList1') 1042 } 1043 .backgroundColor(this.colors[0]) 1044 .columnStart(0) 1045 .columnEnd(1) 1046 1047 GridItem() { 1048 Text('GoodsTypeList2') 1049 } 1050 .backgroundColor(this.colors[1]) 1051 .columnStart(0) 1052 .columnEnd(1) 1053 1054 GridItem() { 1055 Text('GoodsTypeList3') 1056 } 1057 .backgroundColor(this.colors[2]) 1058 .columnStart(0) 1059 .columnEnd(1) 1060 1061 GridItem() { 1062 Text('GoodsTypeList4') 1063 } 1064 .backgroundColor(this.colors[3]) 1065 .columnStart(0) 1066 .columnEnd(1) 1067 1068 GridItem() { 1069 Text('GoodsTypeList5') 1070 } 1071 .backgroundColor(this.colors[4]) 1072 .columnStart(0) 1073 .columnEnd(1) 1074 } 1075 .scrollBar(BarState.Off) 1076 .columnsGap(15) 1077 .rowsGap(10) 1078 .rowsTemplate('1fr 1fr 1fr 1fr 1fr') 1079 .columnsTemplate('1fr') 1080 .width('100%') 1081 .height(200) 1082 } 1083 1084 ListItem() { 1085 Grid(this.gridScroller) { 1086 ForEach(this.numbers, (item: number) => { 1087 GridItem() { 1088 Text(item + '') 1089 .fontSize(16) 1090 .backgroundColor(0xF9CF93) 1091 .width('100%') 1092 .height('100%') 1093 .textAlign(TextAlign.Center) 1094 } 1095 .width('100%') 1096 .height(40) 1097 .shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 }) 1098 .borderRadius(10) 1099 .translate({ x: 0, y: this.translateY }) 1100 }, (item: string) => item) 1101 } 1102 .columnsTemplate('1fr 1fr') 1103 .friction(0.3) 1104 .columnsGap(15) 1105 .rowsGap(10) 1106 .scrollBar(BarState.Off) 1107 .width('100%') 1108 .height('100%') 1109 .layoutDirection(GridDirection.Column) 1110 .nestedScroll({ 1111 scrollForward: NestedScrollMode.PARENT_FIRST, 1112 scrollBackward: NestedScrollMode.SELF_FIRST 1113 }) 1114 .onTouch((event: TouchEvent) => { 1115 if (event.type == TouchType.Down) { 1116 this.listTouchDown = true 1117 } else if (event.type == TouchType.Up) { 1118 this.listTouchDown = false 1119 } 1120 }) 1121 } 1122 } 1123 .scrollBar(BarState.Off) 1124 .edgeEffect(EdgeEffect.None) 1125 .onTouch((event: TouchEvent) => { 1126 if (event.type == TouchType.Down) { 1127 this.touchDown = true 1128 } else if (event.type == TouchType.Up) { 1129 this.touchDown = false 1130 } 1131 }) 1132 .onScrollFrameBegin((offset: number, state: ScrollState) => { 1133 if (this.scrolling && offset > 0) { 1134 let newOffset = this.scroller.currentOffset().yOffset 1135 if (newOffset >= 590) { 1136 this.gridScroller.scrollBy(0, offset) 1137 return { offsetRemain: 0 } 1138 } else if (newOffset + offset > 590) { 1139 this.gridScroller.scrollBy(0, newOffset + offset - 590) 1140 return { offsetRemain: 590 - newOffset } 1141 } 1142 } 1143 return { offsetRemain: offset } 1144 }) 1145 .onScrollStart(() => { 1146 if (this.touchDown && !this.listTouchDown) { 1147 this.scrolling = true 1148 } 1149 }) 1150 .onScrollStop(() => { 1151 this.scrolling = false 1152 }) 1153 } 1154 .width('100%') 1155 .height('100%') 1156 .padding({ left: 10, right: 10 }) 1157 } 1158 1159 Row() { 1160 Text('Top') 1161 .width(30) 1162 .height(30) 1163 .borderRadius(50) 1164 } 1165 .padding(5) 1166 .borderRadius(50) 1167 .backgroundColor('#ffffff') 1168 .shadow({ radius: 10, color: '#909399', offsetX: 1, offsetY: 1 }) 1169 .margin({ right: 22, bottom: 15 }) 1170 .onClick(() => { 1171 this.scroller.scrollTo({ xOffset: 0, yOffset: 0 }) 1172 this.gridScroller.scrollTo({ xOffset: 0, yOffset: 0 }) 1173 }) 1174 } 1175 .align(Alignment.BottomEnd) 1176 } 1177} 1178``` 1179 1180 1181 1182### 示例5(Grid拖拽场景) 1183 11841. 设置属性editMode\(true\)设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem。 11852. 在[onItemDragStart](#onitemdragstart8)回调中设置拖拽过程中显示的图片。 11863. 在[onItemDrop](#onitemdrop8)中获取拖拽起始位置,和拖拽插入位置,并在[onItemDrop](#onitemdrop8)中完成交换数组位置逻辑。 1187 1188> **说明:** 1189> 1190> 预览器窗口不支持显示拖拽跟手。 1191 1192```ts 1193@Entry 1194@Component 1195struct GridExample { 1196 @State numbers: string[] = [] 1197 scroller: Scroller = new Scroller() 1198 @State text: string = 'drag' 1199 1200 @Builder pixelMapBuilder() { //拖拽过程样式 1201 Column() { 1202 Text(this.text) 1203 .fontSize(16) 1204 .backgroundColor(0xF9CF93) 1205 .width(80) 1206 .height(80) 1207 .textAlign(TextAlign.Center) 1208 } 1209 } 1210 1211 aboutToAppear() { 1212 for (let i = 1;i <= 15; i++) { 1213 this.numbers.push(i + '') 1214 } 1215 } 1216 1217 changeIndex(index1: number, index2: number) { //交换数组位置 1218 let temp: string; 1219 temp = this.numbers[index1]; 1220 this.numbers[index1] = this.numbers[index2]; 1221 this.numbers[index2] = temp; 1222 } 1223 1224 build() { 1225 Column({ space: 5 }) { 1226 Grid(this.scroller) { 1227 ForEach(this.numbers, (day: string) => { 1228 GridItem() { 1229 Text(day) 1230 .fontSize(16) 1231 .backgroundColor(0xF9CF93) 1232 .width(80) 1233 .height(80) 1234 .textAlign(TextAlign.Center) 1235 } 1236 }) 1237 } 1238 .columnsTemplate('1fr 1fr 1fr') 1239 .columnsGap(10) 1240 .rowsGap(10) 1241 .width('90%') 1242 .backgroundColor(0xFAEEE0) 1243 .height(300) 1244 .editMode(true) //设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem 1245 .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { //第一次拖拽此事件绑定的组件时,触发回调。 1246 this.text = this.numbers[itemIndex] 1247 return this.pixelMapBuilder() //设置拖拽过程中显示的图片。 1248 }) 1249 .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { //绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。 1250 // isSuccess=false时,说明drop的位置在grid外部;insertIndex > length时,说明有新增元素的事件发生 1251 if (!isSuccess || insertIndex >= this.numbers.length) { 1252 return 1253 } 1254 console.info('beixiang' + itemIndex + '', insertIndex + '') //itemIndex拖拽起始位置,insertIndex拖拽插入位置 1255 this.changeIndex(itemIndex, insertIndex) 1256 }) 1257 }.width('100%').margin({ top: 5 }) 1258 } 1259} 1260``` 1261 1262示例图: 1263 1264网格子组件开始拖拽: 1265 1266 1267 1268网格子组件拖拽过程中: 1269 1270 1271 1272网格子组件1与子组件6拖拽交换位置后: 1273 1274 1275 1276### 示例6(自适应Grid) 1277 1278layoutDirection、maxcount、minCount、cellLength的使用。 1279 1280```ts 1281@Entry 1282@Component 1283struct GridExample { 1284 @State numbers: string[] = [] 1285 1286 aboutToAppear() { 1287 for (let i = 1; i <= 30; i++) { 1288 this.numbers.push(i + '') 1289 } 1290 } 1291 1292 build() { 1293 Scroll() { 1294 Column({ space: 5 }) { 1295 Blank() 1296 Text('rowsTemplate、columnsTemplate都不设置layoutDirection、maxcount、minCount、cellLength才生效') 1297 .fontSize(15).fontColor(0xCCCCCC).width('90%') 1298 Grid() { 1299 ForEach(this.numbers, (day: string) => { 1300 GridItem() { 1301 Text(day).fontSize(16).backgroundColor(0xF9CF93) 1302 }.width(40).height(80).borderWidth(2).borderColor(Color.Red) 1303 }, (day: string) => day) 1304 } 1305 .height(300) 1306 .columnsGap(10) 1307 .rowsGap(10) 1308 .backgroundColor(0xFAEEE0) 1309 .maxCount(6) 1310 .minCount(2) 1311 .cellLength(0) 1312 .layoutDirection(GridDirection.Row) 1313 } 1314 .width('90%').margin({ top: 5, left: 5, right: 5 }) 1315 .align(Alignment.Center) 1316 } 1317 } 1318} 1319``` 1320 1321 1322 1323### 示例7(双指缩放修改Grid列数) 1324 1325双指缩放修改Grid列数。 1326 1327```ts 1328// xxx.ets 1329@Entry 1330@Component 1331struct GridExample { 1332 @State numbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'] 1333 @State columns: number = 2 1334 1335 aboutToAppear() { 1336 let lastCount = AppStorage.get<number>('columnsCount') 1337 if (typeof lastCount != 'undefined') { 1338 this.columns = lastCount 1339 } 1340 } 1341 1342 build() { 1343 Column({ space: 5 }) { 1344 Row() { 1345 Text('双指缩放改变列数') 1346 .height('5%') 1347 .margin({ top: 10, left: 20 }) 1348 } 1349 1350 Grid() { 1351 ForEach(this.numbers, (day: string) => { 1352 ForEach(this.numbers, (day: string) => { 1353 GridItem() { 1354 Text(day) 1355 .fontSize(16) 1356 .backgroundColor(0xF9CF93) 1357 .width('100%') 1358 .height(80) 1359 .textAlign(TextAlign.Center) 1360 } 1361 }, (day: string) => day) 1362 }, (day: string) => day) 1363 } 1364 .columnsTemplate('1fr '.repeat(this.columns)) 1365 .columnsGap(10) 1366 .rowsGap(10) 1367 .width('90%') 1368 .scrollBar(BarState.Off) 1369 .backgroundColor(0xFAEEE0) 1370 .height('100%') 1371 .cachedCount(3) 1372 // 切换列数item位置重排动画 1373 .animation({ 1374 duration: 300, 1375 curve: Curve.Smooth 1376 }) 1377 .priorityGesture( 1378 PinchGesture() 1379 .onActionEnd((event: GestureEvent) => { 1380 console.info('end scale:' + event.scale) 1381 // 手指分开,减少列数以放大Item,触发阈值可以自定义,示例为2 1382 if (event.scale > 2) { 1383 this.columns-- 1384 } else if (event.scale < 0.6) { 1385 this.columns++ 1386 } 1387 // 可以根据设备屏幕宽度设定最大和最小列数,此处以最小1列最大4列为例 1388 this.columns = Math.min(4, Math.max(1, this.columns)); 1389 AppStorage.setOrCreate<number>('columnsCount', this.columns) 1390 }) 1391 ) 1392 }.width('100%').margin({ top: 5 }) 1393 } 1394} 1395``` 1396 1397 1398 1399### 示例8(设置自适应列数) 1400属性[columnsTemplate](#columnstemplate)中auto-fill、auto-fit和auto-stretch的使用示例 1401 1402```ts 1403@Entry 1404@Component 1405struct GridColumnsTemplate { 1406 data: number[] = [0, 1, 2, 3, 4, 5] 1407 data1: number[] = [0, 1, 2, 3, 4, 5] 1408 data2: number[] = [0, 1, 2, 3, 4, 5] 1409 1410 build() { 1411 Column({ space: 10 }) { 1412 Text('auto-fill 根据设定的列宽自动计算列数').width('90%') 1413 Grid() { 1414 ForEach(this.data, (item: number) => { 1415 GridItem() { 1416 Text('N' + item).height(80) 1417 } 1418 .backgroundColor(Color.Orange) 1419 }) 1420 } 1421 .width('90%') 1422 .border({ width: 1, color: Color.Black }) 1423 .columnsTemplate('repeat(auto-fill, 70)') 1424 .columnsGap(10) 1425 .rowsGap(10) 1426 .height(150) 1427 1428 Text('auto-fit 先根据设定的列宽计算列数,余下的空间会均分到每一列中').width('90%') 1429 Grid() { 1430 ForEach(this.data1, (item: number) => { 1431 GridItem() { 1432 Text('N' + item).height(80) 1433 } 1434 .backgroundColor(Color.Orange) 1435 }) 1436 } 1437 .width('90%') 1438 .border({ width: 1, color: Color.Black }) 1439 .columnsTemplate('repeat(auto-fit, 70)') 1440 .columnsGap(10) 1441 .rowsGap(10) 1442 .height(150) 1443 1444 Text('auto-stretch 先根据设定的列宽计算列数,余下的空间会均分到每个列间距中').width('90%') 1445 Grid() { 1446 ForEach(this.data2, (item: number) => { 1447 GridItem() { 1448 Text('N' + item).height(80) 1449 } 1450 .backgroundColor(Color.Orange) 1451 }) 1452 } 1453 .width('90%') 1454 .border({ width: 1, color: Color.Black }) 1455 .columnsTemplate('repeat(auto-stretch, 70)') 1456 .columnsGap(10) 1457 .rowsGap(10) 1458 .height(150) 1459 } 1460 .width('100%') 1461 .height('100%') 1462 } 1463} 1464``` 1465 1466 1467 1468### 示例9(以当前行最高的GridItem的高度为其他GridItem的高度) 1469下面的Grid中包含两列,每列中的GridItem包括高度确定的两个Column和一个高度不确定的Text共三个子组件。 1470 1471在默认情况下,左右两个GridItem的高度可能是不同的;在设置了Grid的[alignItems](#alignitems12)属性为GridItemAlignment.STRETCH后,一行左右两个GridItem中原本高度较小的GridItem会以另一个高度较大的GridItem的高度作为自己的高度。 1472 1473```ts 1474@Entry 1475@Component 1476struct Index { 1477 @State data: number[] = []; 1478 @State items: number[] = []; 1479 1480 aboutToAppear(): void { 1481 for (let i = 0; i < 100; i++) { 1482 this.data.push(i) 1483 this.items.push(this.getSize()) 1484 } 1485 } 1486 1487 getSize() { 1488 let ret = Math.floor(Math.random() * 5) 1489 return Math.max(1, ret) 1490 } 1491 1492 build() { 1493 Column({ space: 10 }) { 1494 Text('Grid alignItems示例代码') 1495 1496 Grid() { 1497 ForEach(this.data, (item: number) => { 1498 // GridItem和Column不设置高度,默认会自适应子组件大小,设置STRETCH的场景下,会变成与当前行最高节点同高。 1499 // 若设置高度,则会保持已设置的高度,不会与当前行最高节点同高。 1500 GridItem() { 1501 Column() { 1502 Column().height(100).backgroundColor('#D5D5D5').width('100%') 1503 // 中间的Text设置flexGrow(1)来自适应填满父组件的空缺 1504 Text('这是一段文字。'.repeat(this.items[item])) 1505 .flexGrow(1).width('100%').align(Alignment.TopStart) 1506 .backgroundColor('#F7F7F7') 1507 Column().height(50).backgroundColor('#707070').width('100%') 1508 } 1509 } 1510 .border({ color: Color.Black, width: 1 }) 1511 }) 1512 } 1513 .columnsGap(10) 1514 .rowsGap(5) 1515 .columnsTemplate('1fr 1fr') 1516 .width('80%') 1517 .height('100%') 1518 // Grid设置alignItems为STRETCH,以当前行最高的GridItem的高度为其他GridItem的高度。 1519 .alignItems(GridItemAlignment.STRETCH) 1520 .scrollBar(BarState.Off) 1521 } 1522 .height('100%') 1523 .width('100%') 1524 } 1525} 1526 1527``` 1528 1529 1530### 示例10(设置边缘渐隐) 1531通过[fadingEdge](ts-container-scrollable-common.md#fadingedge14)属性来设置边缘渐隐效果。 1532 1533```ts 1534// xxx.ets 1535//该示例实现了Grid组件开启边缘渐隐效果并设置边缘渐隐长度 1536import { LengthMetrics } from '@kit.ArkUI' 1537@Entry 1538@Component 1539struct GridExample { 1540 @State numbers: String[] = ['0', '1', '2', '3', '4'] 1541 @State rowNumbers: String[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] 1542 scroller: Scroller = new Scroller() 1543 1544 build() { 1545 Column({ space: 5 }) { 1546 Text('scroll').fontColor(0xCCCCCC).fontSize(9).width('90%') 1547 Grid(this.scroller) { 1548 ForEach(this.rowNumbers, (day: string) => { 1549 ForEach(this.numbers, (day: string) => { 1550 GridItem() { 1551 Text(day) 1552 .fontSize(16) 1553 .backgroundColor(0xF9CF93) 1554 .width('100%') 1555 .height(80) 1556 .textAlign(TextAlign.Center) 1557 } 1558 }, (day: string) => day) 1559 }, (day: string) => day) 1560 } 1561 .columnsTemplate('1fr 1fr 1fr 1fr 1fr') 1562 .columnsGap(10) 1563 .rowsGap(20) 1564 .height('90%') 1565 .fadingEdge(true,{fadingEdgeLength:LengthMetrics.vp(80)}) 1566 1567 }.width('100%').margin({ top: 5 }) 1568 } 1569} 1570``` 1571 1572