• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 组件可见区域变化事件
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiangtao92-->
5<!--Designer: @piggyguy-->
6<!--Tester: @songyanhong-->
7<!--Adviser: @HelloCrease-->
8
9组件可见区域变化事件是组件在屏幕中的显示区域面积变化时触发的事件,提供了判断组件是否完全或部分显示在屏幕中的能力,适用于广告曝光埋点之类的场景。
10
11> **说明:**
12>
13>  从API version 9开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
14
15## onVisibleAreaChange
16
17onVisibleAreaChange(ratios: Array&lt;number&gt;, event: VisibleAreaChangeCallback): T
18
19组件可见区域变化时触发该回调。
20
21**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
22
23**系统能力:** SystemCapability.ArkUI.ArkUI.Full
24
25**参数:**
26
27| 参数名 | 类型                                                | 必填 | 说明                                                         |
28| ------ | --------------------------------------------------- | ---- | ------------------------------------------------------------ |
29| ratios | Array&lt;number&gt;                                 | 是   | 阈值数组。其中,每个阈值代表组件可见面积(即组件在屏幕显示区的面积,只计算父组件内的面积,超出父组件部分不会计算)与组件自身面积的比值。当组件可见面积与自身面积的比值接近阈值时,均会触发该回调。每个阈值的取值范围为[0.0, 1.0],如果开发者设置的阈值超出该范围,则会实际取值0.0或1.0。<br/>**说明:** <br/>当数值接近边界0和1时,将会按照误差不超过0.001的规则进行舍入。例如,0.9997会被近似为1。 |
30| event  | [VisibleAreaChangeCallback](./ts-universal-component-visible-area-change-event.md#visibleareachangecallback12) | 是   | 组件可见区域变化事件的回调。 |
31
32**返回值:**
33
34| 类型 | 说明 |
35| -------- | -------- |
36| T | 返回当前组件。 |
37
38> **说明:**
39>
40>
41>- 仅提供自身节点相对于所有祖先节点(直到window边界)的相对裁切面积与自身面积的比值及其变化趋势。
42>
43>- 不支持兄弟组件对自身节点的遮挡计算,不支持所有祖先的兄弟节点对自身节点的遮挡计算,如[Stack](ts-container-stack.md)、[Z序控制](ts-universal-attributes-z-order.md)等。
44>
45>- 不支持非挂树节点的可见面积变化计算。例如,预加载的节点、通过[overlay](ts-universal-attributes-overlay.md#overlay)能力挂载的自定义节点。
46
47## onVisibleAreaApproximateChange<sup>17+</sup>
48
49onVisibleAreaApproximateChange(options: VisibleAreaEventOptions, event: VisibleAreaChangeCallback | undefined): void
50
51设置[onVisibleAreaChange](./ts-universal-component-visible-area-change-event.md#onvisibleareachange)事件的回调参数,限制它的执行间隔。
52
53**原子化服务API:** 从API version 17开始,该接口支持在原子化服务中使用。
54
55**系统能力:** SystemCapability.ArkUI.ArkUI.Full
56
57**参数:**
58
59| 参数名 | 类型   | 必填 | 说明                       |
60| ------ | ------ | ---- | -------------------------- |
61| options  | [VisibleAreaEventOptions](#visibleareaeventoptions12) | 是   | 可见区域变化相关的参数。 |
62| event  | [VisibleAreaChangeCallback](#visibleareachangecallback12)   \| undefined | 是   | onVisibleAreaChange事件的回调函数。当组件可见面积与自身面积的比值接近options中设置的阈值时触发该回调。 |
63
64>**说明:**
65>
66> 此接口与[onVisibleAreaChange](./ts-universal-component-visible-area-change-event.md#onvisibleareachange)接口存在如下差异,onVisibleAreaChange在每一帧都会进行可见区域比例的计算,如果注册节点太多,系统功耗存在劣化。此接口降低了可见区域比例计算的频度,计算间隔由[VisibleAreaEventOptions](#visibleareaeventoptions12)的expectedUpdateInterval参数决定。
67>
68> 当前接口的可见区域回调阈值默认包含0。例如,开发者设置回调阈值为[0.5],实际生效的阈值为[0.0, 0.5]。
69
70## VisibleAreaEventOptions<sup>12+</sup>
71
72关于区域变化相关的参数。
73
74**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
75
76**系统能力:** SystemCapability.ArkUI.ArkUI.Full
77
78| 参数名 | 类型                                                | 只读 | 可选 | 说明                                                         |
79| ------ | --------------------------------------------------- | ---- | -------- | ------------------------------------------------------------ |
80| ratios | Array&lt;number&gt;                                 | 否 | 否   | 阈值数组。其中,每个阈值代表组件可见面积(即组件在屏幕显示区的面积,只计算父组件内的面积,超出父组件部分不会计算)与组件自身面积的比值。每个阈值的取值范围为[0.0, 1.0],如果开发者设置的阈值超出该范围,则会实际取值0.0或1.0。 |
81| expectedUpdateInterval | number | 否 | 是 | 定义了开发者期望的计算间隔,单位为ms。默认值:1000|
82
83## VisibleAreaChangeCallback<sup>12+</sup>
84
85组件可见区域变化事件的回调类型。
86
87type VisibleAreaChangeCallback = (isExpanding: boolean, currentRatio: number) => void
88
89**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
90
91**系统能力:** SystemCapability.ArkUI.ArkUI.Full
92
93**参数:**
94
95| 参数名            | 类型               | 必填      | 说明                                       |
96| ------------- | ------------------   | ------------- | ---------------------- |
97| isExpanding | boolean | 是 | 视组件的可见面积与自身面积的比值与上一次回调相比的情况而定,比值变大为true,比值变小为false。 |
98| currentRatio | number | 是 | 触发回调时,组件可见面积与自身面积的比值。 |
99
100## 示例
101
102### 示例1 (使用onVisibleAreaChange来监听区域变化)
103
104该示例对组件设置onVisibleAreaChange事件,当组件完全显示或者完全消失时触发回调。
105
106```ts
107// xxx.ets
108@Entry
109@Component
110struct ScrollExample {
111  scroller: Scroller = new Scroller()
112  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
113  @State testTextStr: string = 'test'
114  @State testRowStr: string = 'test'
115
116  build() {
117    Column() {
118      Column() {
119        Text(this.testTextStr)
120          .fontSize(20)
121
122        Text(this.testRowStr)
123          .fontSize(20)
124      }
125      .height(100)
126      .backgroundColor(Color.Gray)
127      .opacity(0.3)
128
129      Scroll(this.scroller) {
130        Column() {
131          Text("Test Text Visible Change")
132            .fontSize(20)
133            .height(200)
134            .margin({ top: 50, bottom: 20 })
135            .backgroundColor(Color.Green)
136              // 通过设置ratios为[0.0, 1.0],实现当组件完全显示或完全消失在屏幕中时触发回调。
137            .onVisibleAreaChange([0.0, 1.0], (isExpanding: boolean, currentRatio: number) => {
138              console.info('Test Text isExpanding: ' + isExpanding + ', currentRatio:' + currentRatio)
139              if (isExpanding && currentRatio >= 1.0) {
140                console.info('Test Text is fully visible. currentRatio:' + currentRatio)
141                this.testTextStr = 'Test Text is fully visible'
142              }
143
144              if (!isExpanding && currentRatio <= 0.0) {
145                console.info('Test Text is completely invisible.')
146                this.testTextStr = 'Test Text is completely invisible'
147              }
148            })
149
150          Row() {
151            Text('Test Row Visible  Change')
152              .fontSize(20)
153              .margin({ bottom: 20 })
154
155          }
156          .height(200)
157          .backgroundColor(Color.Yellow)
158          .onVisibleAreaChange([0.0, 1.0], (isExpanding: boolean, currentRatio: number) => {
159            console.info('Test Row isExpanding:' + isExpanding + ', currentRatio:' + currentRatio)
160            if (isExpanding && currentRatio >= 1.0) {
161              console.info('Test Row is fully visible.')
162              this.testRowStr = 'Test Row is fully visible'
163            }
164
165            if (!isExpanding && currentRatio <= 0.0) {
166              console.info('Test Row is completely invisible.')
167              this.testRowStr = 'Test Row is completely invisible'
168            }
169          })
170
171          ForEach(this.arr, (item:number) => {
172            Text(item.toString())
173              .width('90%')
174              .height(150)
175              .backgroundColor(0xFFFFFF)
176              .borderRadius(15)
177              .fontSize(16)
178              .textAlign(TextAlign.Center)
179              .margin({ top: 10 })
180          }, (item:number) => (item.toString()))
181
182        }.width('100%')
183      }
184      .backgroundColor(0x317aff)
185      .scrollable(ScrollDirection.Vertical)
186      .scrollBar(BarState.On)
187      .scrollBarColor(Color.Gray)
188      .scrollBarWidth(10)
189      .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
190        console.info(xOffset + ' ' + yOffset)
191      })
192      .onScrollEdge((side: Edge) => {
193        console.info('To the edge')
194      })
195      .onScrollStop(() => {
196        console.info('Scroll Stop')
197      })
198
199    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
200  }
201}
202```
203
204### 示例2 (使用onVisibleAreaApproximateChange来监听区域变化)
205
206该示例对组件设置onVisibleAreaApproximateChange事件,当组件完全显示或者完全消失时触发回调。
207
208```ts
209// xxx.ets
210@Entry
211@Component
212struct ScrollExample {
213  scroller: Scroller = new Scroller()
214  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
215  @State testTextStr: string = 'test'
216  @State testRowStr: string = 'test'
217
218  build() {
219    Column() {
220      Column() {
221        Text(this.testTextStr)
222          .fontSize(20)
223
224        Text(this.testRowStr)
225          .fontSize(20)
226      }
227      .height(100)
228      .backgroundColor(Color.Gray)
229      .opacity(0.3)
230
231      Scroll(this.scroller) {
232        Column() {
233          Text("Test Text Visible Change")
234            .fontSize(20)
235            .height(200)
236            .margin({ top: 50, bottom: 20 })
237            .backgroundColor(Color.Green)
238              // 通过设置ratios为[0.0, 1.0],实现当组件完全显示或完全消失在屏幕中时触发回调。
239            .onVisibleAreaApproximateChange({ratios: [0.0, 1.0], expectedUpdateInterval: 1000}, (isExpanding: boolean, currentRatio: number) => {
240              console.info('Test Text isExpanding: ' + isExpanding + ', currentRatio:' + currentRatio)
241              if (isExpanding && currentRatio >= 1.0) {
242                console.info('Test Text is fully visible. currentRatio:' + currentRatio)
243                this.testTextStr = 'Test Text is fully visible'
244              }
245
246              if (!isExpanding && currentRatio <= 0.0) {
247                console.info('Test Text is completely invisible.')
248                this.testTextStr = 'Test Text is completely invisible'
249              }
250            })
251
252          Row() {
253            Text('Test Row Visible  Change')
254              .fontSize(20)
255              .margin({ bottom: 20 })
256
257          }
258          .height(200)
259          .backgroundColor(Color.Yellow)
260          .onVisibleAreaChange([0.0, 1.0], (isExpanding: boolean, currentRatio: number) => {
261            console.info('Test Row isExpanding:' + isExpanding + ', currentRatio:' + currentRatio)
262            if (isExpanding && currentRatio >= 1.0) {
263              console.info('Test Row is fully visible.')
264              this.testRowStr = 'Test Row is fully visible'
265            }
266
267            if (!isExpanding && currentRatio <= 0.0) {
268              console.info('Test Row is completely invisible.')
269              this.testRowStr = 'Test Row is completely invisible'
270            }
271          })
272
273          ForEach(this.arr, (item:number) => {
274            Text(item.toString())
275              .width('90%')
276              .height(150)
277              .backgroundColor(0xFFFFFF)
278              .borderRadius(15)
279              .fontSize(16)
280              .textAlign(TextAlign.Center)
281              .margin({ top: 10 })
282          }, (item:number) => (item.toString()))
283
284        }.width('100%')
285      }
286      .backgroundColor(0x317aff)
287      .scrollable(ScrollDirection.Vertical)
288      .scrollBar(BarState.On)
289      .scrollBarColor(Color.Gray)
290      .scrollBarWidth(10)
291      .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
292        console.info(xOffset + ' ' + yOffset)
293      })
294      .onScrollEdge((side: Edge) => {
295        console.info('To the edge')
296      })
297      .onScrollStop(() => {
298        console.info('Scroll Stop')
299      })
300
301    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
302  }
303}
304```
305![zh-cn_visible_area_change.gif](figures/zh-cn_visible_area_change.gif)
306