1e41f4b71Sopenharmony_ci# Refresh
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciThe **Refresh** component is a container that provides the pull-to-refresh feature.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci>  **NOTE**
6e41f4b71Sopenharmony_ci>
7e41f4b71Sopenharmony_ci>  - This component is supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version.
8e41f4b71Sopenharmony_ci>
9e41f4b71Sopenharmony_ci>  - This component provides linkage with a vertical scrolling **Swiper** and **Web** component since API version 12. The linkage does not work if the **loop** attribute of **Swiper** is set to **true**.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci## Child Components
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ciThis component supports only one child component.
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciSince API version 11, this component's child component moves down with the pull-down gesture.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci## APIs
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciRefresh(value: RefreshOptions)
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci**Parameters**
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci| Name| Type| Mandatory| Description|
28e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
29e41f4b71Sopenharmony_ci| value |  [RefreshOptions](#refreshoptions)| Yes| Parameters of the **Refresh** component.|
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci## RefreshOptions
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci| Name        | Type                                     | Mandatory  | Description                                    |
36e41f4b71Sopenharmony_ci| ---------- | ---------------------------------------- | ---- | ---------------------------------------- |
37e41f4b71Sopenharmony_ci| refreshing | boolean                                  | Yes   | Whether the component is being refreshed. The value **true** means that the component is being refreshed, and **false** means the opposite.<br>Default value: **false**<br>This parameter supports [$$](../../../quick-start/arkts-two-way-sync.md) for two-way binding of variables.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
38e41f4b71Sopenharmony_ci| offset<sup>(deprecated)</sup>    | string \| number               | No   | Distance from the pull-down starting point to the top of the component.<br>Default value: **16**, in vp<br>This API is deprecated since API version 11. No substitute API is provided.<br>**NOTE**<br>The value range of **offset** is [0vp, 64vp]. If the value is greater than 64 vp, the value 64 vp will be used. The value cannot be a percentage or a negative number.|
39e41f4b71Sopenharmony_ci| friction<sup>(deprecated)</sup>   | number \| string               | No   | Coefficient of friction, which indicates the **<Refresh\>** component's sensitivity to the pull-down gesture. The value ranges from 0 to 100.<br>Default value: **62**<br>- **0** indicates that the **Refresh** component is not responsive to the pull-down gesture.<br>- **100** indicates that the **Refresh** component is highly responsive to the pull-down gesture.<br>- A larger value indicates higher responsiveness of the **Refresh** component to the pull-down gesture.<br>This API is deprecated since API version 11. You can use [pullDownRatio](#pulldownratio12) instead since API version 12.|
40e41f4b71Sopenharmony_ci| builder<sup>10+</sup>    | [CustomBuilder](ts-types.md#custombuilder8) | No   | Custom content in the refreshing area.<br>**NOTE**<br>In API version 10 and earlier versions, there is a height limit of 64 vp on custom components. This restriction is removed since API version 11.<br>When a custom component is set with a fixed height, it will be displayed below the refreshing area at that fixed height; when the custom component does not have a height set, its height will adapt to the height of the refreshing area, which may result in the height of the custom component changing to 0 along with the refreshing area. To prevent its height from being less than expected, you are advised to set a minimum height constraint for the custom component. For reference, see [Example 2](#example-2).<br>Since API version 12, use **refreshingContent** instead of **builder** for customizing the content of the refreshing area, to avoid animation interruptions caused by the destruction and re-creation of the custom component during the refreshing process.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
41e41f4b71Sopenharmony_ci| promptText<sup>12+</sup> | [ResourceStr](ts-types.md#resourcestr) | No| Custom text displayed at the bottom of the refreshing area.<br>**NOTE**<br>When setting the text, follow the constraints on the **Text** components. If you are using **builder** or **refreshingContent** to customize the content displayed in the refreshing area, the text set with **promptText** will not be displayed.<br>When **promptText** is set and effective, the [refreshOffset](#refreshoffset12) attribute defaults to 96 vp.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
42e41f4b71Sopenharmony_ci| refreshingContent<sup>12+</sup>    | [ComponentContent](../js-apis-arkui-ComponentContent.md) | No   | Custom content in the refreshing area.<br>**NOTE**<br>If this parameter and the **builder** parameter are set at the same time, the **builder** parameter does not take effect.<br>When a custom component is set with a fixed height, it will be displayed below the refreshing area at that fixed height; when the custom component does not have a height set, its height will adapt to the height of the refreshing area, which may result in the height of the custom component changing to 0 along with the refreshing area. To prevent its height from being less than expected, you are advised to set a minimum height constraint for the custom component. For reference, see [Example 5](#example-5).<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci## Attributes
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ciIn addition to the [universal attributes](ts-universal-attributes-size.md), the following attributes are supported.
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci### refreshOffset<sup>12+</sup>
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_cirefreshOffset(value: number)
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ciSets the pull-down offset that initiates a refresh.
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12.
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ci**Parameters**
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci| Name| Type                                       | Mandatory| Description                                                      |
61e41f4b71Sopenharmony_ci| ------ | ------------------------------------------- | ---- | ---------------------------------------------------------- |
62e41f4b71Sopenharmony_ci| value  | number |  Yes| Pull-down offset, in vp.<br>Default value: 96 vp when [promptText](#refreshoptions) is set and 64 vp when [promptText](#refreshoptions) is not<br>If the value specified is 0 or less than 0, the default value is used.|
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci### pullToRefresh<sup>12+</sup>
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_cipullToRefresh(value: boolean)
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ciSets whether to initiate a refresh when the pull-down distance exceeds the value of [refreshOffset](#refreshoffset12).
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12.
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci**Parameters**
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci| Name| Type                                       | Mandatory| Description                                                      |
77e41f4b71Sopenharmony_ci| ------ | ------------------------------------------- | ---- | ---------------------------------------------------------- |
78e41f4b71Sopenharmony_ci| value  | boolean |  Yes| Whether to initiate a refresh when the pull-down distance exceeds the value of [refreshOffset](#refreshoffset12). The value **true** means to initiate a refresh, and **false** means the opposite.<br>Default value: **true**|
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci### pullDownRatio<sup>12+</sup>
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_cipullDownRatio(ratio: [Optional](ts-universal-attributes-custom-property.md#optional12)\<number>)
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ciSets the pull-down ratio.
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12.
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci**Parameters**
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci| Name| Type                                       | Mandatory| Description                                                      |
93e41f4b71Sopenharmony_ci| ------ | ------------------------------------------- | ---- | ---------------------------------------------------------- |
94e41f4b71Sopenharmony_ci| ratio  | [Optional](ts-universal-attributes-custom-property.md#optional12)\<number> |  Yes| Pull-down ratio. A larger value indicates higher responsiveness to the pull-down gesture. The value **0** indicates that the pull-down does not follow the gesture, and **1** indicates that the pull-down follows the gesture proportionally.<br>If this parameter is not set or is set to **undefined**, a dynamic pull-down ratio is used. That is, the larger the pull-down distance, the smaller the ratio.<br>The value ranges from 0 to 1. A value less than 0 is handled as **0**, and a value greater than 1 is handled as **1**.
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci## Events
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ciIn addition to the [universal events](ts-universal-events-click.md), the following events are supported.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci### onStateChange
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_cionStateChange(callback: (state: RefreshStatus) => void)
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ciCalled when the refresh status changes.
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11.
107e41f4b71Sopenharmony_ci
108e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
109e41f4b71Sopenharmony_ci
110e41f4b71Sopenharmony_ci**Parameters**
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci| Name| Type                                   | Mandatory| Description      |
113e41f4b71Sopenharmony_ci| ------ | --------------------------------------- | ---- | ---------- |
114e41f4b71Sopenharmony_ci| state  | [RefreshStatus](#refreshstatus) | Yes  | Refresh status.|
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci### onRefreshing
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_cionRefreshing(callback: () => void)
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ciCalled when the component starts refreshing.
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11.
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci### onOffsetChange<sup>12+</sup>
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_cionOffsetChange(callback: Callback\<number>)
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ciCalled when the pull-down distance changes.
131e41f4b71Sopenharmony_ci
132e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12.
133e41f4b71Sopenharmony_ci
134e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci**Parameters**
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci| Name| Type                                   | Mandatory| Description      |
139e41f4b71Sopenharmony_ci| ------ | --------------------------------------- | ---- | ---------- |
140e41f4b71Sopenharmony_ci| value  | number | Yes  | Pull-down distance.<br>Unit: vp|
141e41f4b71Sopenharmony_ci
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci## RefreshStatus
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 11.
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci| Name      | Value      | Description                  |
150e41f4b71Sopenharmony_ci| -------- | -------- | -------------------- |
151e41f4b71Sopenharmony_ci| Inactive | 0 | The component is not pulled down. This is the default value.            |
152e41f4b71Sopenharmony_ci| Drag     | 1 | The component is being pulled down, but the pull-down distance is shorter than the minimum length required to trigger the refresh.     |
153e41f4b71Sopenharmony_ci| OverDrag | 2 | The component is being pulled down, and the pull-down distance exceeds the minimum length required to trigger the refresh.     |
154e41f4b71Sopenharmony_ci| Refresh  | 3 | The pull-down ends, and the component rebounds to the minimum length required to trigger the refresh and enters the refreshing state.|
155e41f4b71Sopenharmony_ci| Done     | 4 | The refresh is complete, and the component returns to the initial state (at the top).    |
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci## Example
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ci### Example 1
161e41f4b71Sopenharmony_ci
162e41f4b71Sopenharmony_ciThis example implements a **Refresh** with its refreshing area in the default style.
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ci```ts
165e41f4b71Sopenharmony_ci// xxx.ets
166e41f4b71Sopenharmony_ci@Entry
167e41f4b71Sopenharmony_ci@Component
168e41f4b71Sopenharmony_cistruct RefreshExample {
169e41f4b71Sopenharmony_ci  @State isRefreshing: boolean = false
170e41f4b71Sopenharmony_ci  @State arr: String[] = ['0', '1', '2', '3', '4','5','6','7','8','9','10']
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_ci  build() {
173e41f4b71Sopenharmony_ci    Column() {
174e41f4b71Sopenharmony_ci      Refresh({ refreshing: $$this.isRefreshing}) {
175e41f4b71Sopenharmony_ci        List() {
176e41f4b71Sopenharmony_ci          ForEach(this.arr, (item: string) => {
177e41f4b71Sopenharmony_ci            ListItem() {
178e41f4b71Sopenharmony_ci              Text('' + item)
179e41f4b71Sopenharmony_ci                .width('70%').height(80).fontSize(16).margin(10)
180e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
181e41f4b71Sopenharmony_ci            }
182e41f4b71Sopenharmony_ci          }, (item: string) => item)
183e41f4b71Sopenharmony_ci        }
184e41f4b71Sopenharmony_ci        .onScrollIndex((first: number) => {
185e41f4b71Sopenharmony_ci          console.info(first.toString())
186e41f4b71Sopenharmony_ci        })
187e41f4b71Sopenharmony_ci        .width('100%')
188e41f4b71Sopenharmony_ci        .height('100%')
189e41f4b71Sopenharmony_ci        .alignListItem(ListItemAlign.Center)
190e41f4b71Sopenharmony_ci        .scrollBar(BarState.Off)
191e41f4b71Sopenharmony_ci      }
192e41f4b71Sopenharmony_ci      .onStateChange((refreshStatus: RefreshStatus) => {
193e41f4b71Sopenharmony_ci        console.info('Refresh onStatueChange state is ' + refreshStatus)
194e41f4b71Sopenharmony_ci      })
195e41f4b71Sopenharmony_ci      .onOffsetChange((value: number) => {
196e41f4b71Sopenharmony_ci        console.info('Refresh onOffsetChange offset:' + value)
197e41f4b71Sopenharmony_ci      })
198e41f4b71Sopenharmony_ci      .onRefreshing(() => {
199e41f4b71Sopenharmony_ci        setTimeout(() => {
200e41f4b71Sopenharmony_ci          this.isRefreshing = false
201e41f4b71Sopenharmony_ci        }, 2000)
202e41f4b71Sopenharmony_ci        console.log('onRefreshing test')
203e41f4b71Sopenharmony_ci      })
204e41f4b71Sopenharmony_ci      .backgroundColor(0x89CFF0)
205e41f4b71Sopenharmony_ci      .refreshOffset(64)
206e41f4b71Sopenharmony_ci      .pullToRefresh(true)
207e41f4b71Sopenharmony_ci    }
208e41f4b71Sopenharmony_ci  }
209e41f4b71Sopenharmony_ci}
210e41f4b71Sopenharmony_ci```
211e41f4b71Sopenharmony_ci
212e41f4b71Sopenharmony_ci![en-us_image_refresh_example1](figures/en-us_image_refresh_example1.gif)
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci### Example 2
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ciThis example implements a **Refresh** with its refreshing area displaying the custom content defined with **builder**.
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ci```ts
219e41f4b71Sopenharmony_ci// xxx.ets
220e41f4b71Sopenharmony_ci@Entry
221e41f4b71Sopenharmony_ci@Component
222e41f4b71Sopenharmony_cistruct RefreshExample {
223e41f4b71Sopenharmony_ci  @State isRefreshing: boolean = false
224e41f4b71Sopenharmony_ci  @State arr: String[] = ['0', '1', '2', '3', '4','5','6','7','8','9','10']
225e41f4b71Sopenharmony_ci  @Builder
226e41f4b71Sopenharmony_ci  customRefreshComponent()
227e41f4b71Sopenharmony_ci  {
228e41f4b71Sopenharmony_ci    Stack()
229e41f4b71Sopenharmony_ci    {
230e41f4b71Sopenharmony_ci      Row()
231e41f4b71Sopenharmony_ci      {
232e41f4b71Sopenharmony_ci        LoadingProgress().height(32)
233e41f4b71Sopenharmony_ci        Text("Refreshing...").fontSize(16).margin({left:20})
234e41f4b71Sopenharmony_ci      }
235e41f4b71Sopenharmony_ci      .alignItems(VerticalAlign.Center)
236e41f4b71Sopenharmony_ci    }
237e41f4b71Sopenharmony_ci    .align(Alignment.Center)
238e41f4b71Sopenharmony_ci    .clip(true)
239e41f4b71Sopenharmony_ci    .constraintSize({minHeight:32}) // Setting a minimum height constraint ensures that the height of the custom component does not fall below the specified minHeight when the height of the refreshing area changes.
240e41f4b71Sopenharmony_ci    .width("100%")
241e41f4b71Sopenharmony_ci  }
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci  build() {
244e41f4b71Sopenharmony_ci    Column() {
245e41f4b71Sopenharmony_ci      Refresh({ refreshing: $$this.isRefreshing,builder:this.customRefreshComponent()}) {
246e41f4b71Sopenharmony_ci        List() {
247e41f4b71Sopenharmony_ci          ForEach(this.arr, (item: string) => {
248e41f4b71Sopenharmony_ci            ListItem() {
249e41f4b71Sopenharmony_ci              Text('' + item)
250e41f4b71Sopenharmony_ci                .width('70%').height(80).fontSize(16).margin(10)
251e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
252e41f4b71Sopenharmony_ci            }
253e41f4b71Sopenharmony_ci          }, (item: string) => item)
254e41f4b71Sopenharmony_ci        }
255e41f4b71Sopenharmony_ci        .onScrollIndex((first: number) => {
256e41f4b71Sopenharmony_ci          console.info(first.toString())
257e41f4b71Sopenharmony_ci        })
258e41f4b71Sopenharmony_ci        .width('100%')
259e41f4b71Sopenharmony_ci        .height('100%')
260e41f4b71Sopenharmony_ci        .alignListItem(ListItemAlign.Center)
261e41f4b71Sopenharmony_ci        .scrollBar(BarState.Off)
262e41f4b71Sopenharmony_ci      }
263e41f4b71Sopenharmony_ci      .backgroundColor(0x89CFF0)
264e41f4b71Sopenharmony_ci      .pullToRefresh(true)
265e41f4b71Sopenharmony_ci      .refreshOffset(64)
266e41f4b71Sopenharmony_ci      .onStateChange((refreshStatus: RefreshStatus) => {
267e41f4b71Sopenharmony_ci        console.info('Refresh onStatueChange state is ' + refreshStatus)
268e41f4b71Sopenharmony_ci      })
269e41f4b71Sopenharmony_ci      .onRefreshing(() => {
270e41f4b71Sopenharmony_ci        setTimeout(() => {
271e41f4b71Sopenharmony_ci          this.isRefreshing = false
272e41f4b71Sopenharmony_ci        }, 2000)
273e41f4b71Sopenharmony_ci        console.log('onRefreshing test')
274e41f4b71Sopenharmony_ci      })
275e41f4b71Sopenharmony_ci    }
276e41f4b71Sopenharmony_ci  }
277e41f4b71Sopenharmony_ci}
278e41f4b71Sopenharmony_ci```
279e41f4b71Sopenharmony_ci
280e41f4b71Sopenharmony_ci![en-us_image_refresh_example2](figures/en-us_image_refresh_example2.gif)
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ci### Example 3
283e41f4b71Sopenharmony_ci
284e41f4b71Sopenharmony_ciThis example implements a **Refresh** component that produces a bounce effect when the boundary is reached.
285e41f4b71Sopenharmony_ci
286e41f4b71Sopenharmony_ci```ts
287e41f4b71Sopenharmony_ci// Index.ets
288e41f4b71Sopenharmony_ci@Entry
289e41f4b71Sopenharmony_ci@Component
290e41f4b71Sopenharmony_cistruct ListRefreshLoad {
291e41f4b71Sopenharmony_ci  @State arr: Array<number> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
292e41f4b71Sopenharmony_ci  @State refreshing: boolean = false;
293e41f4b71Sopenharmony_ci  @State refreshOffset: number = 0;
294e41f4b71Sopenharmony_ci  @State refreshState: RefreshStatus = RefreshStatus.Inactive;
295e41f4b71Sopenharmony_ci  @State canLoad: boolean = false;
296e41f4b71Sopenharmony_ci  @State isLoading: boolean = false;
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci  @Builder
299e41f4b71Sopenharmony_ci  refreshBuilder() {
300e41f4b71Sopenharmony_ci    Stack({ alignContent: Alignment.Bottom }) {
301e41f4b71Sopenharmony_ci      // can use the refresh state to decide whether the progress component is exist or not.
302e41f4b71Sopenharmony_ci      // in this case, the component is not exist otherwise in the pull down or refresh state
303e41f4b71Sopenharmony_ci      if (this.refreshState != RefreshStatus.Inactive && this.refreshState != RefreshStatus.Done) {
304e41f4b71Sopenharmony_ci        Progress({ value: this.refreshOffset, total: 64, type: ProgressType.Ring })
305e41f4b71Sopenharmony_ci          .width(32).height(32)
306e41f4b71Sopenharmony_ci          .style({ status: this.refreshing ? ProgressStatus.LOADING : ProgressStatus.PROGRESSING })
307e41f4b71Sopenharmony_ci          .margin(10)
308e41f4b71Sopenharmony_ci      }
309e41f4b71Sopenharmony_ci    }
310e41f4b71Sopenharmony_ci    .clip(true)
311e41f4b71Sopenharmony_ci    .height("100%")
312e41f4b71Sopenharmony_ci    .width("100%")
313e41f4b71Sopenharmony_ci  }
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci  @Builder
316e41f4b71Sopenharmony_ci  footer() {
317e41f4b71Sopenharmony_ci    Row() {
318e41f4b71Sopenharmony_ci      LoadingProgress().height(32).width(48)
319e41f4b71Sopenharmony_ci      Text("Loading")
320e41f4b71Sopenharmony_ci    }.width("100%")
321e41f4b71Sopenharmony_ci    .height(64)
322e41f4b71Sopenharmony_ci    .justifyContent(FlexAlign.Center)
323e41f4b71Sopenharmony_ci    // hidden this component when don't need to load
324e41f4b71Sopenharmony_ci    .visibility(this.isLoading ? Visibility.Visible : Visibility.Hidden)
325e41f4b71Sopenharmony_ci  }
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci  build() {
328e41f4b71Sopenharmony_ci    Refresh({ refreshing: $$this.refreshing, builder: this.refreshBuilder() }) {
329e41f4b71Sopenharmony_ci      List() {
330e41f4b71Sopenharmony_ci        ForEach(this.arr, (item: number) => {
331e41f4b71Sopenharmony_ci          ListItem() {
332e41f4b71Sopenharmony_ci            Text('' + item)
333e41f4b71Sopenharmony_ci              .width('100%')
334e41f4b71Sopenharmony_ci              .height(80)
335e41f4b71Sopenharmony_ci              .fontSize(16)
336e41f4b71Sopenharmony_ci              .textAlign(TextAlign.Center)
337e41f4b71Sopenharmony_ci              .backgroundColor(0xFFFFFF)
338e41f4b71Sopenharmony_ci          }.borderWidth(1)
339e41f4b71Sopenharmony_ci        }, (item: string) => item)
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ci        ListItem() {
342e41f4b71Sopenharmony_ci          this.footer();
343e41f4b71Sopenharmony_ci        }
344e41f4b71Sopenharmony_ci      }
345e41f4b71Sopenharmony_ci      .onScrollIndex((start: number, end: number) => {
346e41f4b71Sopenharmony_ci        // when reach the end of list, trigger data load
347e41f4b71Sopenharmony_ci        if (this.canLoad && end >= this.arr.length - 1) {
348e41f4b71Sopenharmony_ci          this.canLoad = false;
349e41f4b71Sopenharmony_ci          this.isLoading = true;
350e41f4b71Sopenharmony_ci          // simulate trigger data load
351e41f4b71Sopenharmony_ci          setTimeout(() => {
352e41f4b71Sopenharmony_ci            for (let i = 0; i < 10; i++) {
353e41f4b71Sopenharmony_ci              this.arr.push(this.arr.length);
354e41f4b71Sopenharmony_ci              this.isLoading = false;
355e41f4b71Sopenharmony_ci            }
356e41f4b71Sopenharmony_ci          }, 700)
357e41f4b71Sopenharmony_ci        }
358e41f4b71Sopenharmony_ci      })
359e41f4b71Sopenharmony_ci      .onScrollFrameBegin((offset: number, state: ScrollState) => {
360e41f4b71Sopenharmony_ci        // loading can be triggered only when swipe up
361e41f4b71Sopenharmony_ci        if (offset > 5 && !this.isLoading) {
362e41f4b71Sopenharmony_ci          this.canLoad = true;
363e41f4b71Sopenharmony_ci        }
364e41f4b71Sopenharmony_ci        return { offsetRemain: offset };
365e41f4b71Sopenharmony_ci      })
366e41f4b71Sopenharmony_ci      .scrollBar(BarState.Off)
367e41f4b71Sopenharmony_ci      // open the spring back of edge
368e41f4b71Sopenharmony_ci      .edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })
369e41f4b71Sopenharmony_ci    }
370e41f4b71Sopenharmony_ci    .width('100%')
371e41f4b71Sopenharmony_ci    .height('100%')
372e41f4b71Sopenharmony_ci    .backgroundColor(0xDCDCDC)
373e41f4b71Sopenharmony_ci    .onOffsetChange((offset: number) => {
374e41f4b71Sopenharmony_ci      this.refreshOffset = offset;
375e41f4b71Sopenharmony_ci    })
376e41f4b71Sopenharmony_ci    .onStateChange((state: RefreshStatus) => {
377e41f4b71Sopenharmony_ci      this.refreshState = state;
378e41f4b71Sopenharmony_ci    })
379e41f4b71Sopenharmony_ci    .onRefreshing(() => {
380e41f4b71Sopenharmony_ci      // simulate refresh the data
381e41f4b71Sopenharmony_ci      setTimeout(() => {
382e41f4b71Sopenharmony_ci        this.refreshing = false;
383e41f4b71Sopenharmony_ci      }, 2000)
384e41f4b71Sopenharmony_ci    })
385e41f4b71Sopenharmony_ci  }
386e41f4b71Sopenharmony_ci}
387e41f4b71Sopenharmony_ci```
388e41f4b71Sopenharmony_ci
389e41f4b71Sopenharmony_ci![refresh_boundary_resilience](figures/refresh_boundary_resilience.gif)
390e41f4b71Sopenharmony_ci
391e41f4b71Sopenharmony_ci### Example 4
392e41f4b71Sopenharmony_ci
393e41f4b71Sopenharmony_ciThis example demonstrates how to use **promptText** to set the text displayed in the refreshing area.
394e41f4b71Sopenharmony_ci
395e41f4b71Sopenharmony_ci```ts
396e41f4b71Sopenharmony_ci// xxx.ets
397e41f4b71Sopenharmony_ci@Entry
398e41f4b71Sopenharmony_ci@Component
399e41f4b71Sopenharmony_cistruct RefreshExample {
400e41f4b71Sopenharmony_ci  @State isRefreshing: boolean = false
401e41f4b71Sopenharmony_ci  @State promptText: string = "Refreshing..."
402e41f4b71Sopenharmony_ci  @State arr: String[] = ['0', '1', '2', '3', '4','5','6','7','8','9','10']
403e41f4b71Sopenharmony_ci
404e41f4b71Sopenharmony_ci  build() {
405e41f4b71Sopenharmony_ci    Column() {
406e41f4b71Sopenharmony_ci      Refresh({ refreshing: $$this.isRefreshing, promptText: this.promptText}) {
407e41f4b71Sopenharmony_ci        List() {
408e41f4b71Sopenharmony_ci          ForEach(this.arr, (item: string) => {
409e41f4b71Sopenharmony_ci            ListItem() {
410e41f4b71Sopenharmony_ci              Text('' + item)
411e41f4b71Sopenharmony_ci                .width('70%').height(80).fontSize(16).margin(10)
412e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
413e41f4b71Sopenharmony_ci            }
414e41f4b71Sopenharmony_ci          }, (item: string) => item)
415e41f4b71Sopenharmony_ci        }
416e41f4b71Sopenharmony_ci        .onScrollIndex((first: number) => {
417e41f4b71Sopenharmony_ci          console.info(first.toString())
418e41f4b71Sopenharmony_ci        })
419e41f4b71Sopenharmony_ci        .width('100%')
420e41f4b71Sopenharmony_ci        .height('100%')
421e41f4b71Sopenharmony_ci        .alignListItem(ListItemAlign.Center)
422e41f4b71Sopenharmony_ci        .scrollBar(BarState.Off)
423e41f4b71Sopenharmony_ci      }
424e41f4b71Sopenharmony_ci      .backgroundColor(0x89CFF0)
425e41f4b71Sopenharmony_ci      .pullToRefresh(true)
426e41f4b71Sopenharmony_ci      .refreshOffset(96)
427e41f4b71Sopenharmony_ci      .onStateChange((refreshStatus: RefreshStatus) => {
428e41f4b71Sopenharmony_ci        console.info('Refresh onStatueChange state is ' + refreshStatus)
429e41f4b71Sopenharmony_ci      })
430e41f4b71Sopenharmony_ci      .onOffsetChange((value: number) => {
431e41f4b71Sopenharmony_ci        console.info('Refresh onOffsetChange offset:' + value)
432e41f4b71Sopenharmony_ci      })
433e41f4b71Sopenharmony_ci      .onRefreshing(() => {
434e41f4b71Sopenharmony_ci        setTimeout(() => {
435e41f4b71Sopenharmony_ci          this.isRefreshing = false
436e41f4b71Sopenharmony_ci        }, 2000)
437e41f4b71Sopenharmony_ci        console.log('onRefreshing test')
438e41f4b71Sopenharmony_ci      })
439e41f4b71Sopenharmony_ci    }
440e41f4b71Sopenharmony_ci  }
441e41f4b71Sopenharmony_ci}
442e41f4b71Sopenharmony_ci```
443e41f4b71Sopenharmony_ci
444e41f4b71Sopenharmony_ci![en-us_image_refresh_example4](figures/en-us_image_refresh_example4.gif)
445e41f4b71Sopenharmony_ci
446e41f4b71Sopenharmony_ci### Example 5
447e41f4b71Sopenharmony_ci
448e41f4b71Sopenharmony_ciThis example implements a **Refresh** with its refreshing area displaying the custom content defined with **refreshingContent**.
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci```ts
451e41f4b71Sopenharmony_ciimport { ComponentContent } from '@ohos.arkui.node';
452e41f4b71Sopenharmony_ci
453e41f4b71Sopenharmony_ciclass Params {
454e41f4b71Sopenharmony_ci  refreshStatus: RefreshStatus = RefreshStatus.Inactive
455e41f4b71Sopenharmony_ci
456e41f4b71Sopenharmony_ci  constructor(refreshStatus: RefreshStatus) {
457e41f4b71Sopenharmony_ci    this.refreshStatus = refreshStatus;
458e41f4b71Sopenharmony_ci  }
459e41f4b71Sopenharmony_ci}
460e41f4b71Sopenharmony_ci
461e41f4b71Sopenharmony_ci@Builder
462e41f4b71Sopenharmony_cifunction customRefreshingContent(params:Params) {
463e41f4b71Sopenharmony_ci  Stack() {
464e41f4b71Sopenharmony_ci    Row() {
465e41f4b71Sopenharmony_ci      LoadingProgress().height(32)
466e41f4b71Sopenharmony_ci      Text("refreshStatus: "+params.refreshStatus).fontSize(16).margin({left:20})
467e41f4b71Sopenharmony_ci    }
468e41f4b71Sopenharmony_ci    .alignItems(VerticalAlign.Center)
469e41f4b71Sopenharmony_ci  }
470e41f4b71Sopenharmony_ci  .align(Alignment.Center)
471e41f4b71Sopenharmony_ci  .clip(true)
472e41f4b71Sopenharmony_ci  .constraintSize({minHeight:32}) // Setting a minimum height constraint ensures that the height of the custom component does not fall below the specified minHeight when the height of the refreshing area changes.
473e41f4b71Sopenharmony_ci  .width("100%")
474e41f4b71Sopenharmony_ci}
475e41f4b71Sopenharmony_ci
476e41f4b71Sopenharmony_ci@Entry
477e41f4b71Sopenharmony_ci@Component
478e41f4b71Sopenharmony_cistruct RefreshExample {
479e41f4b71Sopenharmony_ci  @State isRefreshing: boolean = false
480e41f4b71Sopenharmony_ci  @State arr: String[] = ['0', '1', '2', '3', '4','5','6','7','8','9','10']
481e41f4b71Sopenharmony_ci  @State refreshStatus: RefreshStatus = RefreshStatus.Inactive
482e41f4b71Sopenharmony_ci  private contentNode?: ComponentContent<Object> = undefined
483e41f4b71Sopenharmony_ci
484e41f4b71Sopenharmony_ci  aboutToAppear():void {
485e41f4b71Sopenharmony_ci    let uiContext = this.getUIContext();
486e41f4b71Sopenharmony_ci    this.contentNode = new ComponentContent(uiContext, wrapBuilder(customRefreshingContent), new Params(this.refreshStatus))
487e41f4b71Sopenharmony_ci  }
488e41f4b71Sopenharmony_ci
489e41f4b71Sopenharmony_ci  build() {
490e41f4b71Sopenharmony_ci    Column() {
491e41f4b71Sopenharmony_ci      Refresh({ refreshing: $$this.isRefreshing, refreshingContent:this.contentNode}) {
492e41f4b71Sopenharmony_ci        List() {
493e41f4b71Sopenharmony_ci          ForEach(this.arr, (item: string) => {
494e41f4b71Sopenharmony_ci            ListItem() {
495e41f4b71Sopenharmony_ci              Text('' + item)
496e41f4b71Sopenharmony_ci                .width('70%').height(80).fontSize(16).margin(10)
497e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
498e41f4b71Sopenharmony_ci            }
499e41f4b71Sopenharmony_ci          }, (item: string) => item)
500e41f4b71Sopenharmony_ci        }
501e41f4b71Sopenharmony_ci        .onScrollIndex((first: number) => {
502e41f4b71Sopenharmony_ci          console.info(first.toString())
503e41f4b71Sopenharmony_ci        })
504e41f4b71Sopenharmony_ci        .width('100%')
505e41f4b71Sopenharmony_ci        .height('100%')
506e41f4b71Sopenharmony_ci        .alignListItem(ListItemAlign.Center)
507e41f4b71Sopenharmony_ci        .scrollBar(BarState.Off)
508e41f4b71Sopenharmony_ci      }
509e41f4b71Sopenharmony_ci      .backgroundColor(0x89CFF0)
510e41f4b71Sopenharmony_ci      .pullToRefresh(true)
511e41f4b71Sopenharmony_ci      .refreshOffset(96)
512e41f4b71Sopenharmony_ci      .onStateChange((refreshStatus: RefreshStatus) => {
513e41f4b71Sopenharmony_ci        this.refreshStatus = refreshStatus
514e41f4b71Sopenharmony_ci        this.contentNode?.update(new Params(this.refreshStatus)) // Update the content of the custom component.
515e41f4b71Sopenharmony_ci        console.info('Refresh onStatueChange state is ' + refreshStatus)
516e41f4b71Sopenharmony_ci      })
517e41f4b71Sopenharmony_ci      .onRefreshing(() => {
518e41f4b71Sopenharmony_ci        setTimeout(() => {
519e41f4b71Sopenharmony_ci          this.isRefreshing = false
520e41f4b71Sopenharmony_ci        }, 2000)
521e41f4b71Sopenharmony_ci        console.log('onRefreshing test')
522e41f4b71Sopenharmony_ci      })
523e41f4b71Sopenharmony_ci    }
524e41f4b71Sopenharmony_ci  }
525e41f4b71Sopenharmony_ci}
526e41f4b71Sopenharmony_ci```
527e41f4b71Sopenharmony_ci![en-us_image_refresh_example5](figures/en-us_image_refresh_example5.gif)
528e41f4b71Sopenharmony_ci
529e41f4b71Sopenharmony_ci### Example 6
530e41f4b71Sopenharmony_ci
531e41f4b71Sopenharmony_ciThis example shows how to use the [pullDownRatio](#pulldownratio12) attribute and the [onOffsetChange](#onoffsetchange12) event to implement the maximum pull-down distance.
532e41f4b71Sopenharmony_ci
533e41f4b71Sopenharmony_ci```ts
534e41f4b71Sopenharmony_ciimport { ComponentContent } from '@ohos.arkui.node';
535e41f4b71Sopenharmony_ci
536e41f4b71Sopenharmony_ci@Builder
537e41f4b71Sopenharmony_cifunction customRefreshingContent() {
538e41f4b71Sopenharmony_ci  Stack() {
539e41f4b71Sopenharmony_ci    Row() {
540e41f4b71Sopenharmony_ci      LoadingProgress().height(32)
541e41f4b71Sopenharmony_ci    }
542e41f4b71Sopenharmony_ci    .alignItems(VerticalAlign.Center)
543e41f4b71Sopenharmony_ci  }
544e41f4b71Sopenharmony_ci  .align(Alignment.Center)
545e41f4b71Sopenharmony_ci  .clip(true)
546e41f4b71Sopenharmony_ci  .constraintSize({minHeight:32}) // Setting a minimum height constraint ensures that the height of the custom component does not fall below the specified minHeight when the height of the refreshing area changes.
547e41f4b71Sopenharmony_ci  .width("100%")
548e41f4b71Sopenharmony_ci}
549e41f4b71Sopenharmony_ci
550e41f4b71Sopenharmony_ci@Entry
551e41f4b71Sopenharmony_ci@Component
552e41f4b71Sopenharmony_cistruct RefreshExample {
553e41f4b71Sopenharmony_ci  @State isRefreshing: boolean = false
554e41f4b71Sopenharmony_ci  @State arr: String[] = ['0', '1', '2', '3', '4','5','6','7','8','9','10']
555e41f4b71Sopenharmony_ci  @State maxRefreshingHeight: number = 100.0
556e41f4b71Sopenharmony_ci  @State ratio: number = 1
557e41f4b71Sopenharmony_ci  private contentNode?: ComponentContent<Object> = undefined
558e41f4b71Sopenharmony_ci
559e41f4b71Sopenharmony_ci  aboutToAppear():void {
560e41f4b71Sopenharmony_ci    let uiContext = this.getUIContext();
561e41f4b71Sopenharmony_ci    this.contentNode = new ComponentContent(uiContext, wrapBuilder(customRefreshingContent))
562e41f4b71Sopenharmony_ci  }
563e41f4b71Sopenharmony_ci
564e41f4b71Sopenharmony_ci  build() {
565e41f4b71Sopenharmony_ci    Column() {
566e41f4b71Sopenharmony_ci      Refresh({ refreshing: $$this.isRefreshing, refreshingContent:this.contentNode}) {
567e41f4b71Sopenharmony_ci        List() {
568e41f4b71Sopenharmony_ci          ForEach(this.arr, (item: string) => {
569e41f4b71Sopenharmony_ci            ListItem() {
570e41f4b71Sopenharmony_ci              Text('' + item)
571e41f4b71Sopenharmony_ci                .width('70%').height(80).fontSize(16).margin(10)
572e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)
573e41f4b71Sopenharmony_ci            }
574e41f4b71Sopenharmony_ci          }, (item: string) => item)
575e41f4b71Sopenharmony_ci        }
576e41f4b71Sopenharmony_ci        .onScrollIndex((first: number) => {
577e41f4b71Sopenharmony_ci          console.info(first.toString())
578e41f4b71Sopenharmony_ci        })
579e41f4b71Sopenharmony_ci        .width('100%')
580e41f4b71Sopenharmony_ci        .height('100%')
581e41f4b71Sopenharmony_ci        .alignListItem(ListItemAlign.Center)
582e41f4b71Sopenharmony_ci        .scrollBar(BarState.Off)
583e41f4b71Sopenharmony_ci      }
584e41f4b71Sopenharmony_ci      .backgroundColor(0x89CFF0)
585e41f4b71Sopenharmony_ci      .pullDownRatio(this.ratio)
586e41f4b71Sopenharmony_ci      .pullToRefresh(true)
587e41f4b71Sopenharmony_ci      .refreshOffset(64)
588e41f4b71Sopenharmony_ci      .onOffsetChange((offset: number)=>{
589e41f4b71Sopenharmony_ci          this.ratio = 1 - Math.pow((offset / this.maxRefreshingHeight), 3) // The closer to the maximum pull-down distance, the smaller the pull-down ratio.
590e41f4b71Sopenharmony_ci      })
591e41f4b71Sopenharmony_ci      .onStateChange((refreshStatus: RefreshStatus) => {
592e41f4b71Sopenharmony_ci        console.info('Refresh onStatueChange state is ' + refreshStatus)
593e41f4b71Sopenharmony_ci      })
594e41f4b71Sopenharmony_ci      .onRefreshing(() => {
595e41f4b71Sopenharmony_ci        setTimeout(() => {
596e41f4b71Sopenharmony_ci          this.isRefreshing = false
597e41f4b71Sopenharmony_ci        }, 2000)
598e41f4b71Sopenharmony_ci        console.log('onRefreshing test')
599e41f4b71Sopenharmony_ci      })
600e41f4b71Sopenharmony_ci    }
601e41f4b71Sopenharmony_ci  }
602e41f4b71Sopenharmony_ci}
603e41f4b71Sopenharmony_ci```
604e41f4b71Sopenharmony_ci
605e41f4b71Sopenharmony_ci![en-us_image_refresh_example6](figures/en-us_image_refresh_example6.gif)
606