• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# LazyVGridLayout
2
3The **LazyVGridLayout** component implements a lazy-loading grid layout, with its parent component restricted to [WaterFlow](ts-container-waterflow.md) or [FlowItem](ts-container-flowitem.md). It can also be used within the **WaterFlow** or **FlowItem** component after being wrapped by custom components or [NodeContainer](ts-basic-components-nodecontainer.md).
4
5Lazy loading is supported only when the **WaterFlow** component uses single-column mode or single-column segments in segmented layout and the layout direction is **FlexDirection.Column**. Lazy loading is not supported if the **WaterFlow** component is in multi-column mode or the layout direction is **FlexDirection.Row** or **FlexDirection.RowReverse**. Using this component with **FlexDirection.ColumnReverse** in the **WaterFlow** component causes display anomalies. When lazy loading is enabled, the component only loads child components within the **WaterFlow** visible area, with pre-loading of half-screen content above and below the viewport during frame idle periods.
6
7> **NOTE**
8>
9> - This component is supported since API version 19. Updates will be marked with a superscript to indicate their earliest API version.
10> - This component's height adapts to content by default. Setting the height, height constraints, or aspect ratio causes display anomalies.
11
12## APIs
13
14LazyVGridLayout()
15
16Creates a vertical lazy-loading grid layout container.
17
18**Atomic service API**: This API can be used in atomic services since API version 19.
19
20**System capability**: SystemCapability.ArkUI.ArkUI.Full
21
22## Attributes
23
24In addition to the [universal attributes](ts-component-general-attributes.md), the following attributes are supported.
25
26### columnsTemplate
27
28columnsTemplate(value: string)
29
30Sets the number of columns, fixed column width, or minimum column width of the grid. If this attribute is not set, one column will be used.
31
32For example, **'1fr 1fr 2fr'** indicates three columns, with the first column taking up 1/4 of the parent component's full width, the second column 1/4, and the third column 2/4.
33
34**columnsTemplate('repeat(auto-fit, track-size)')**: The layout automatically calculates the number of columns and the actual column width, while adhering to the minimum column width specified with **track-size**.
35
36**columnsTemplate('repeat(auto-fill, track-size)')**: The layout automatically calculates the number of columns based on the fixed column width specified with **track-size**.
37
38**columnsTemplate('repeat(auto-stretch, track-size)')**: The layout uses **columnsGap** to define the minimum gap between columns and automatically calculates the number of columns and the actual gap size based on the fixed column width specified with **track-size**.
39
40**repeat**, **auto-fit**, **auto-fill**, and **auto-stretch** are keywords. **track-size** indicates the column width, in the unit of px, vp (default), %, or any valid digit. The value must be greater than or equal to one valid column width.<br>
41In **auto-stretch** mode, **track-size** must be a valid column width value, in the unit of px, vp, or any valid digit; percentage values (%) are not supported.
42
43If this attribute is set to **'0fr'**, the column width is 0, and child components are not displayed. If this attribute is set to an invalid value, the child components are displayed in a fixed column.
44
45**Atomic service API**: This API can be used in atomic services since API version 19.
46
47**System capability**: SystemCapability.ArkUI.ArkUI.Full
48
49**Parameters**
50
51| Name| Type  | Mandatory| Description                              |
52| ------ | ------ | ---- | ---------------------------------- |
53| value  | string | Yes  | Number of columns or minimum column width of the grid.|
54
55### columnsGap
56
57columnsGap(value: LengthMetrics): T
58
59Sets the gap between columns. A value less than 0 evaluates to the default value.
60
61**Atomic service API**: This API can be used in atomic services since API version 19.
62
63**System capability**: SystemCapability.ArkUI.ArkUI.Full
64
65**Parameters**
66
67| Name| Type                        | Mandatory| Description                        |
68| ------ | ---------------------------- | ---- | ---------------------------- |
69| value  |  [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | Yes  | Gap between columns.<br>Default value: **0vp**|
70
71**Return value**
72
73| Type| Description          |
74| --- | -------------- |
75| T | Current component.|
76
77### rowsGap
78
79rowsGap(value: LengthMetrics): T
80
81Sets the gap between rows. A value less than 0 evaluates to the default value.
82
83**Atomic service API**: This API can be used in atomic services since API version 19.
84
85**System capability**: SystemCapability.ArkUI.ArkUI.Full
86
87**Parameters**
88
89| Name| Type                        | Mandatory| Description                        |
90| ------ | ---------------------------- | ---- | ---------------------------- |
91| value  | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12) | Yes  | Gap between rows.<br>Default value: **0vp**|
92
93**Return value**
94
95| Type| Description          |
96| --- | -------------- |
97| T | Current component.|
98
99## Events
100
101Only the [universal events](ts-component-general-events.md) are supported.
102
103## Example
104
105This example demonstrates how to implement a lazy-loading grid layout using the **WaterFlow** and **LazyVGridLayout** components.
106
107<!--code_no_check-->
108```ts
109import { LengthMetrics } from '@kit.ArkUI'
110import { MyDataSource } from './MyDataSource'
111
112@Entry
113@Component
114struct LazyVGridLayoutSample1 {
115  private arr:MyDataSource<number> = new MyDataSource<number>();
116  build() {
117    Column() {
118      WaterFlow() {
119        LazyVGridLayout() {
120          LazyForEach(this.arr, (item:number)=>{
121            Text("item" + item.toString())
122              .height(64)
123              .width("100%")
124              .borderRadius(5)
125              .backgroundColor(Color.White)
126              .textAlign(TextAlign.Center)
127          })
128        }
129        .columnsTemplate("1fr 1fr")
130        .rowsGap(LengthMetrics.vp(10))
131        .columnsGap(LengthMetrics.vp(10))
132      }.padding(10)
133    }
134    .width('100%').height('100%')
135    .backgroundColor("#DCDCDC")
136  }
137
138  aboutToAppear(): void {
139    for (let i = 0; i < 100; i++) {
140      this.arr.pushData(i);
141    }
142  }
143}
144```
145
146<!--code_no_check-->
147```ts
148// MyDataSource.ets
149export class BasicDataSource<T> implements IDataSource {
150  private listeners: DataChangeListener[] = [];
151  protected dataArray: T[] = [];
152
153  public totalCount(): number {
154    return this.dataArray.length;
155  }
156
157  public getData(index: number): T {
158    return this.dataArray[index];
159  }
160
161  registerDataChangeListener(listener: DataChangeListener): void {
162    if (this.listeners.indexOf(listener) < 0) {
163      console.info('add listener');
164      this.listeners.push(listener);
165    }
166  }
167
168  unregisterDataChangeListener(listener: DataChangeListener): void {
169    const pos = this.listeners.indexOf(listener);
170    if (pos >= 0) {
171      console.info('remove listener');
172      this.listeners.splice(pos, 1);
173    }
174  }
175
176  notifyDataReload(): void {
177    this.listeners.forEach(listener => {
178      listener.onDataReloaded();
179    })
180  }
181
182  notifyDataAdd(index: number): void {
183    this.listeners.forEach(listener => {
184      listener.onDataAdd(index);
185    })
186  }
187
188  notifyDataChange(index: number): void {
189    this.listeners.forEach(listener => {
190      listener.onDataChange(index);
191    })
192  }
193
194  notifyDataDelete(index: number): void {
195    this.listeners.forEach(listener => {
196      listener.onDataDelete(index);
197    })
198  }
199
200  notifyDataMove(from: number, to: number): void {
201    this.listeners.forEach(listener => {
202      listener.onDataMove(from, to);
203    })
204  }
205
206  notifyDatasetChange(operations: DataOperation[]): void {
207    this.listeners.forEach(listener => {
208      listener.onDatasetChange(operations);
209    })
210  }
211}
212
213export class MyDataSource<T> extends BasicDataSource<T> {
214  public shiftData(): void {
215    this.dataArray.shift();
216    this.notifyDataDelete(0);
217  }
218  public unshiftData(data: T): void {
219    this.dataArray.unshift(data);
220    this.notifyDataAdd(0);
221  }
222  public pushData(data: T): void {
223    this.dataArray.push(data);
224    this.notifyDataAdd(this.dataArray.length - 1);
225  }
226  public popData(): void {
227    this.dataArray.pop();
228    this.notifyDataDelete(this.dataArray.length);
229  }
230  public clearData(): void {
231    this.dataArray = [];
232    this.notifyDataReload();
233  }
234}
235```
236
237![](figures/en-us_image_lazyvgridlayout1.png)
238