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