• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Visible Area Change Event
2
3The visible area change event of a component refers to the change in the visual portion of the component on the screen. It can be used to determine whether the component is completely or partially displayed on the screen. It is usually applicable to scenarios such as advertisement exposure tracing.
4
5> **NOTE**
6>
7>  The APIs of this module are supported since API version 9. Updates will be marked with a superscript to indicate their earliest API version.
8
9## onVisibleAreaChange
10
11onVisibleAreaChange(ratios: Array<number>, event: VisibleAreaChangeCallback): T
12
13Called when the visible area of the component changes.
14
15**Atomic service API**: This API can be used in atomic services since API version 11.
16
17**System capability**: SystemCapability.ArkUI.ArkUI.Full
18
19**Parameters**
20
21| Name| Type                                               | Mandatory| Description                                                        |
22| ------ | --------------------------------------------------- | ---- | ------------------------------------------------------------ |
23| ratios | Array&lt;number&gt;                                 | Yes  | Threshold array. Each threshold represents a ratio of the component's visible area (that is, the area of the component that is visible on screen; only the area within the parent component is counted) to the component's total area. This callback is invoked when the ratio of the component's visible area to its total area is greater than or less than the threshold. The value range of the threshold is [0.0, 1.0]. If the threshold set exceeds this range, the value **0.0** or **1.0** will be used.<br>**NOTE**<br>When the value is close to the boundary 0 or 1, it is rounded off with a round-off error not greater than 0.001. For example, 0.9997 is rounded off to 1.|
24| event  | [VisibleAreaChangeCallback](ts-types.md#visibleareachangecallback12) | Yes  | Callback for visible area changes of the component.|
25
26**Return value**
27
28| Type| Description|
29| -------- | -------- |
30| T | Current component.|
31
32> **NOTE**
33>
34>
35>- This API only takes into account the relative clipped area ratio of the component with respect to all ancestor nodes (up to the window boundary) and its own area.
36>
37>- It does not support calculations for obstructions caused by sibling components or by sibling components of any ancestors, such as those managed by [Stack](ts-container-stack.md) or [z-order control](ts-universal-attributes-z-order.md).
38>
39>- It does not support visibility change calculations for nodes that are not in the component tree. For example, preloaded nodes or custom nodes mounted using the [overlay](ts-universal-attributes-overlay.md#overlay) capability.
40
41## onVisibleAreaApproximateChange<sup>17+</sup>
42
43onVisibleAreaApproximateChange(options: VisibleAreaEventOptions, event: VisibleAreaChangeCallback | undefined): void
44
45Called to set the callback parameters for the [onVisibleAreaChange](./ts-universal-component-visible-area-change-event.md#onvisibleareachange) event to restrict its execution interval.
46
47**Atomic service API**: This API can be used in atomic services since API version 17.
48
49**System capability**: SystemCapability.ArkUI.ArkUI.Full
50
51**Parameters**
52
53| Name| Type  | Mandatory| Description                      |
54| ------ | ------ | ---- | -------------------------- |
55| options  | [VisibleAreaEventOptions](./ts-types.md#visibleareaeventoptions12) | Yes  | Options of visible area changes.|
56| event  | [VisibleAreaChangeCallback](./ts-types.md#visibleareachangecallback12)   \| undefined | Yes  | Callback for the **onVisibleAreaChange** event. This callback is triggered when the ratio of the component's visible area to its total area approaches the threshold set in **options**.|
57
58>**NOTE**
59>
60> This callback is not a real-time callback. The actual callback interval may differ from the expected interval.
61>
62> The interval between two visible area change callbacks will not be less than the expected update interval. If the provided expected interval is too short, the actual callback interval will be determined by the system load.
63>
64> By default, the interval threshold of the visible area change callback includes 0. This means that, if the provided threshold is [0.5], the effective threshold will be [0.0, 0.5].
65
66## Example
67
68### Example 1: Using onVisibleAreaChange to Listen for Visible Area Changes
69
70This example demonstrates how to set an **onVisibleAreaChange** event for a component, which triggers the callback when the component is fully displayed or completely hidden.
71
72```ts
73// xxx.ets
74@Entry
75@Component
76struct ScrollExample {
77  scroller: Scroller = new Scroller()
78  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
79  @State testTextStr: string = 'test'
80  @State testRowStr: string = 'test'
81
82  build() {
83    Column() {
84      Column() {
85        Text(this.testTextStr)
86          .fontSize(20)
87
88        Text(this.testRowStr)
89          .fontSize(20)
90      }
91      .height(100)
92      .backgroundColor(Color.Gray)
93      .opacity(0.3)
94
95      Scroll(this.scroller) {
96        Column() {
97          Text("Test Text Visible Change")
98            .fontSize(20)
99            .height(200)
100            .margin({ top: 50, bottom: 20 })
101            .backgroundColor(Color.Green)
102              // Set ratios to [0.0, 1.0] to invoke the callback when the component is fully visible or invisible on screen.
103            .onVisibleAreaChange([0.0, 1.0], (isExpanding: boolean, currentRatio: number) => {
104              console.info('Test Text isExpanding: ' + isExpanding + ', currentRatio:' + currentRatio)
105              if (isExpanding && currentRatio >= 1.0) {
106                console.info('Test Text is fully visible. currentRatio:' + currentRatio)
107                this.testTextStr = 'Test Text is fully visible'
108              }
109
110              if (!isExpanding && currentRatio <= 0.0) {
111                console.info('Test Text is completely invisible.')
112                this.testTextStr = 'Test Text is completely invisible'
113              }
114            })
115
116          Row() {
117            Text('Test Row Visible  Change')
118              .fontSize(20)
119              .margin({ bottom: 20 })
120
121          }
122          .height(200)
123          .backgroundColor(Color.Yellow)
124          .onVisibleAreaChange([0.0, 1.0], (isExpanding: boolean, currentRatio: number) => {
125            console.info('Test Row isExpanding:' + isExpanding + ', currentRatio:' + currentRatio)
126            if (isExpanding && currentRatio >= 1.0) {
127              console.info('Test Row is fully visible.')
128              this.testRowStr = 'Test Row is fully visible'
129            }
130
131            if (!isExpanding && currentRatio <= 0.0) {
132              console.info('Test Row is completely invisible.')
133              this.testRowStr = 'Test Row is completely invisible'
134            }
135          })
136
137          ForEach(this.arr, (item:number) => {
138            Text(item.toString())
139              .width('90%')
140              .height(150)
141              .backgroundColor(0xFFFFFF)
142              .borderRadius(15)
143              .fontSize(16)
144              .textAlign(TextAlign.Center)
145              .margin({ top: 10 })
146          }, (item:number) => (item.toString()))
147
148        }.width('100%')
149      }
150      .backgroundColor(0x317aff)
151      .scrollable(ScrollDirection.Vertical)
152      .scrollBar(BarState.On)
153      .scrollBarColor(Color.Gray)
154      .scrollBarWidth(10)
155      .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
156        console.info(xOffset + ' ' + yOffset)
157      })
158      .onScrollEdge((side: Edge) => {
159        console.info('To the edge')
160      })
161      .onScrollStop(() => {
162        console.info('Scroll Stop')
163      })
164
165    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
166  }
167}
168```
169
170### Example 2: Using onVisibleAreaApproximateChange to Listen for Visible Area Changes
171
172This example demonstrates how to set an **onVisibleAreaApproximateChange** event for a component, which triggers the callback when the component is fully displayed or completely hidden.
173
174```ts
175// xxx.ets
176@Entry
177@Component
178struct ScrollExample {
179  scroller: Scroller = new Scroller()
180  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
181  @State testTextStr: string = 'test'
182  @State testRowStr: string = 'test'
183
184  build() {
185    Column() {
186      Column() {
187        Text(this.testTextStr)
188          .fontSize(20)
189
190        Text(this.testRowStr)
191          .fontSize(20)
192      }
193      .height(100)
194      .backgroundColor(Color.Gray)
195      .opacity(0.3)
196
197      Scroll(this.scroller) {
198        Column() {
199          Text("Test Text Visible Change")
200            .fontSize(20)
201            .height(200)
202            .margin({ top: 50, bottom: 20 })
203            .backgroundColor(Color.Green)
204              // Set ratios to [0.0, 1.0] to invoke the callback when the component is fully visible or invisible on screen.
205            .onVisibleAreaApproximateChange({ratios: [0.0, 1.0], expectedUpdateInterval: 1000}, (isExpanding: boolean, currentRatio: number) => {
206              console.info('Test Text isExpanding: ' + isExpanding + ', currentRatio:' + currentRatio)
207              if (isExpanding && currentRatio >= 1.0) {
208                console.info('Test Text is fully visible. currentRatio:' + currentRatio)
209                this.testTextStr = 'Test Text is fully visible'
210              }
211
212              if (!isExpanding && currentRatio <= 0.0) {
213                console.info('Test Text is completely invisible.')
214                this.testTextStr = 'Test Text is completely invisible'
215              }
216            })
217
218          Row() {
219            Text('Test Row Visible Change')
220              .fontSize(20)
221              .margin({ bottom: 20 })
222
223          }
224          .height(200)
225          .backgroundColor(Color.Yellow)
226          .onVisibleAreaChange([0.0, 1.0], (isExpanding: boolean, currentRatio: number) => {
227            console.info('Test Row isExpanding:' + isExpanding + ', currentRatio:' + currentRatio)
228            if (isExpanding && currentRatio >= 1.0) {
229              console.info('Test Row is fully visible.')
230              this.testRowStr = 'Test Row is fully visible'
231            }
232
233            if (!isExpanding && currentRatio <= 0.0) {
234              console.info('Test Row is completely invisible.')
235              this.testRowStr = 'Test Row is completely invisible'
236            }
237          })
238
239          ForEach(this.arr, (item:number) => {
240            Text(item.toString())
241              .width('90%')
242              .height(150)
243              .backgroundColor(0xFFFFFF)
244              .borderRadius(15)
245              .fontSize(16)
246              .textAlign(TextAlign.Center)
247              .margin({ top: 10 })
248          }, (item:number) => (item.toString()))
249
250        }.width('100%')
251      }
252      .backgroundColor(0x317aff)
253      .scrollable(ScrollDirection.Vertical)
254      .scrollBar(BarState.On)
255      .scrollBarColor(Color.Gray)
256      .scrollBarWidth(10)
257      .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
258        console.info(xOffset + ' ' + yOffset)
259      })
260      .onScrollEdge((side: Edge) => {
261        console.info('To the edge')
262      })
263      .onScrollStop(() => {
264        console.info('Scroll Stop')
265      })
266
267    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
268  }
269}
270```
271![en-us_visible_area_change.gif](figures/en-us_visible_area_change.gif)
272