• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# UIExtensionComponent (系统接口)
2
3UIExtensionComponent用于支持在本页面内嵌入其他应用提供的UI。展示的内容在另外一个进程中运行,本应用并不参与其中的布局和渲染。
4
5通常用于有进程隔离诉求的模块化开发场景。
6
7> **说明:**
8>
9> 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
10>
11> 本模块为系统接口。
12
13## 使用约束
14
15本组件不支持预览。
16
17被拉起的Ability必须是带UI的Ability扩展,如何实现带UI的Ability扩展请参考[实现带UI的Ability扩展](../../apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)。
18
19必须显式设置组件宽高为非0有效值。
20
21不支持滚动到边界后,传递至上层继续滚动的场景。当UIExtensionComponent组件使用方和扩展Ability都支持内容滚动时,通过手势滚动会导致UIExtensionComponent内外同时响应,包括但不限于[Scroll](ts-container-scroll.md)、[Swiper](ts-container-swiper.md)、[List](ts-container-list.md)、[Grid](ts-container-grid.md)等滚动容器。内外手势同时滚动场景的规避方法可参考[示例2](#示例2-uec内外部同时响应滚动时隔离处理)。
22
23
24## 子组件
25
2627
28## 接口
29
30UIExtensionComponent(want: Want, options?: UIExtensionOptions)
31
32**参数:**
33
34| 参数名                | 参数类型                                                   | 必填 | 参数描述           |
35| --------------------- | ---------------------------------------------------------- | ---- | ------------------ |
36| want                  | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) | 是   | 要加载的Ability。  |
37| options<sup>11+</sup> | [UIExtensionOptions](#uiextensionoptions11)                | 否   | 需要传递的构造项。 |
38
39## 属性
40
41支持[通用属性](ts-component-general-attributes.md)。
42
43## 事件
44
45不支持[点击](ts-universal-events-click.md)等通用事件。
46
47将事件经过坐标转换后传递给对端Ability处理。
48
49支持以下事件:
50
51### onRemoteReady
52
53onRemoteReady(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<UIExtensionProxy>)
54
55UIExtensionAbility连接完成时的回调,之后可使用proxy向被拉起的Ability发送数据。
56
57**参数:**
58
59| 参数名                       | 类型   | 说明                                                         |
60| ---------------------------- | ------ | ------------------------------------------------------------ |
61| proxy                        | UIExtensionProxy | 用于向对端Ability发送数据。                          |
62
63### onReceive
64
65onReceive(callback: ReceiveCallback)
66
67收到被拉起的Ability发送的数据时触发的回调。
68
69**参数:**
70
71| 参数名                       | 类型   | 说明                                                         |
72| ---------------------------- | ------ | ------------------------------------------------------------ |
73| data                        | [ReceiveCallback](#receivecallback18) | 收到来自对端Ability的数据。                 |
74
75### onResult<sup>(deprecated)</sup>
76
77onResult(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{code: number; want?: Want}>)
78
79被拉起的Ability扩展调用terminateSelfWithResult时会先触发本回调函数,再触发OnRelease。
80
81本回调内可处理对端Ability的结果数据,可参考[AbilityResult](../../apis-ability-kit/js-apis-inner-ability-abilityResult.md)。
82
83> **说明:**
84> 从 API version 10 开始支持,从 API version 12 开始废弃,建议使用[onTerminated](#onterminated12)替代。
85
86**参数:**
87
88| 参数名                       | 类型   | 说明                                                         |
89| ---------------------------- | ------ | ------------------------------------------------------------ |
90| code                        | number | 收到来自对端Ability的处理結果code。                          |
91| want                        | Want | 收到来自对端Ability的处理結果[Want](../../apis-ability-kit/js-apis-app-ability-want.md)。 |
92
93### onRelease<sup>(deprecated)</sup>
94
95onRelease(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number>)
96
97用于处理被拉起的Ability销毁时的回调。
98
99被拉起的Ability扩展调用terminateSelfWithResult或者terminateSelf时会触发本回调,此时releaseCode为0,即正常销毁。
100
101被拉起的Ability扩展意外Crash或被kill时,触发本回调,此时releaseCode为1。
102
103> **说明:**
104> 从 API version 10 开始支持,从 API version 12 开始废弃,建议使用[onTerminated](#onterminated12)或者[onError](#onerror)替代。
105
106**参数:**
107
108| 参数名                       | 类型   | 说明                                                         |
109| ---------------------------- | ------ | ------------------------------------------------------------ |
110| releaseCode                        | number | 对端Ability销毁时的code,0为正常销毁,1为异常销毁。                          |
111
112### onError
113
114onError(callback:[ErrorCallback](../../apis-basic-services-kit/js-apis-base.md#errorcallback))
115
116被拉起的Ability扩展在运行过程中发生异常时触发本回调。可通过回调参数中的code、name和message获取错误信息并做处理。
117
118**参数:**
119
120| 参数名                       | 类型   | 说明                                                         |
121| ---------------------------- | ------ | ------------------------------------------------------------ |
122| err                        | [BusinessError](../../apis-basic-services-kit/js-apis-base.md#businesserror) | 报错信息。    |
123
124### onTerminated<sup>12+<sup>
125
126onTerminated(callback: Callback&lt;TerminationInfo&gt;)
127
128被拉起的UIExtensionAbility通过调用`terminateSelfWithResult`或者`terminateSelf`正常退出时,触发本回调函数。
129
130**参数:**
131
132| 参数名   | 类型   | 说明                                                                                     |
133| -------  | ------ | ---------------------------------------------------------------------------------------- |
134| callback | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<[TerminationInfo](#terminationinfo12)> | 回调函数,入参用于接收UIExtensionAbility的返回结果,类型为[TerminationInfo](#terminationinfo12)。 |
135
136> **说明:**
137>
138> - 若UIExtensionAbility通过调用`terminateSelfWithResult`退出,其携带的信息会传给回调函数的入参。
139> - 若UIExtensionAbility通过调用`terminateSelf`退出,上述回调函数的入参中,"code"取默认值"0","want"为"undefined"。
140
141### onDrawReady<sup>18+<sup>
142
143onDrawReady(callback: Callback\<void>)
144
145被拉起的UIExtensionAbility绘制第一帧时触发本回调。
146
147**参数:**
148
149| 参数名                       | 类型   | 说明                                                         |
150| ---------------------------- | ------ | ------------------------------------------------------------ |
151| callback                        | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback) \<void> | 回调函数,UIExtensionAbility绘制第一帧时触发本回调,类型为void。    |
152
153### TerminationInfo<sup>12+<sup>
154
155用于表示被拉起的UIExtensionAbility通过调用`terminateSelfWithResult`或者`terminateSelf`正常退出时的返回结果。
156
157| 属性名  | 类型   | 说明                                                 |
158| ------- | ------ | ---------------------------------------------------  |
159| code    | number | 被拉起UIExtensionAbility退出时返回的结果码。 |
160| want    | [Want](../../apis-ability-kit/js-apis-app-ability-want.md)   | 被拉起UIExtensionAbility退出时返回的数据。   |
161
162## ReceiveCallback<sup>18+<sup>
163type ReceiveCallback = Callback\<Record\<string, Object\>\>
164
165用于封装被拉起的Ability发送的数据。
166
167**系统能力:** SystemCapability.ArkUI.ArkUI.Full
168
169**参数:**
170| 参数名                       | 类型   | 说明                                                         |
171| ---------------------------- | ------ | ------------------------------------------------------------ |
172| data                        | Record\<string, Object\> | 收到来自对端Ability的数据。                 |
173
174## UIExtensionOptions<sup>11+</sup>
175用于在UIExtensionComponent进行构造的时传递可选的构造参数。
176
177**参数:**
178
179| 参数名               | 参数类型                                 | 必填 | 参数描述                                                                                                      |
180| ----                 | ---------------------------------------- | ---- | ---------------                                                                                               |
181| isTransferringCaller | boolean                                  | 否   | 在使用UIExtensionComponent嵌套时,设置当前UIExtensionComponent是否转发上一级的Caller信息。</br> 默认值:false。 |
182| placeholder<sup>12+<sup> | [ComponentContent](../js-apis-arkui-ComponentContent.md)       | 否   | 设置占位符,在UIExtensionComponent与UIExtensionAbility建立连接前显示。 |
183| dpiFollowStrategy<sup>12+<sup> | [DpiFollowStrategy](ts-container-ui-extension-component-sys.md#dpifollowstrategy12)                  | 否   | 提供接口支持设置DPI跟随宿主或跟随UIExtensionAbility。</br> 默认值:FOLLOW_UI_EXTENSION_ABILITY_DPI。 |
184| areaChangePlaceholder<sup>14+<sup> | Record<string, [ComponentContent](../js-apis-arkui-ComponentContent.md)>       | 否   | 设置尺寸变化占位符,在UIExtensionComponent尺寸发生变化并且UIExtension内部渲染未完成时显示, key值支持"FOLD_TO_EXPAND"(折叠展开尺寸变化)、"UNDEFINED"(默认尺寸变化)。 |
185| windowModeFollowStrategy<sup>18+<sup> | [WindowModeFollowStrategy](ts-container-ui-extension-component-sys.md#windowmodefollowstrategy18)    | 否   | 提供接口以支持设置窗口Mode,使其能够跟随宿主或UIExtensionAbility。</br> 默认值:FOLLOW_UI_EXTENSION_ABILITY_WINDOW_MODE。 |
186
187## DpiFollowStrategy<sup>12+</sup>
188
189| 名称                             | 描述             |
190| -------------------------------- | --------------- |
191| FOLLOW_HOST_DPI                  | 表示DPI跟随宿主。 |
192| FOLLOW_UI_EXTENSION_ABILITY_DPI  | 表示DPI跟随UIExtensionAbility。 |
193
194## WindowModeFollowStrategy<sup>18+</sup>
195
196窗口Mode跟随策略,用于设置窗口Mode,使其能够跟随宿主或UIExtensionAbility。
197
198| 名称                                     | 值  | 描述             |
199| ---------------------------------------- | ----|--------------- |
200| FOLLOW_HOST_WINDOW_MODE                  | 0   | 表示窗口Mode跟随宿主。 |
201| FOLLOW_UI_EXTENSION_ABILITY_WINDOW_MODE  | 1   | 表示窗口Mode跟随UIExtensionAbility。 |
202
203## UIExtensionProxy
204
205用于在双方建立连接成功后,组件使用方向被拉起的Ability发送数据、订阅和取消订阅注册。
206
207### send
208
209send(data: Record\<string, Object\>): void
210
211用于在双方建立连接成功后,组件使用方向被拉起的Ability发送数据的场景,提供异步发送数据。
212
213**系统能力:** SystemCapability.ArkUI.ArkUI.Full
214
215**参数:**
216
217| 参数名  | 参数类型                                     | 必填   | 参数描述            |
218| ---- | ---------------------------------------- | ---- | --------------- |
219| data | Record\<string, Object\> | 是    | 异步发送给被拉起的扩展Ability的数据。 |
220
221### sendSync<sup>11+</sup>
222
223sendSync(data: Record\<string, Object\>): Record\<string, Object\>
224
225用于在双方建立连接成功后,组件使用方向被拉起的Ability发送数据的场景,提供同步发送数据。
226
227**系统能力:** SystemCapability.ArkUI.ArkUI.Full
228
229**参数:**
230
231| 参数名  | 参数类型                                     | 必填   | 参数描述            |
232| ---- | ---------------------------------------- | ---- | --------------- |
233| data | Record\<string, Object\> | 是    | 同步发送给被拉起的扩展Ability的数据。 |
234
235**返回值:**
236
237| 类型 | 描述 |
238| ---- | ----|
239| Record\<string, Object\> | 扩展Ability回复的数据。 |
240
241**错误码:**
242
243| 错误号 | 描述 |
244| ---- | ----|
245| 100011 | 扩展Ability未注册同步回调 |
246| 100012 | 数据发送失败 |
247
248### on('asyncReceiverRegister')<sup>11+</sup>
249
250on(type: 'asyncReceiverRegister', callback: Callback\<UIExtensionProxy\>): void
251
252用于在双方建立连接成功后,组件使用方订阅被拉起的Ability发生异步注册的场景。
253
254**系统能力:** SystemCapability.ArkUI.ArkUI.Full
255
256**参数:**
257
258| 参数名  | 参数类型 |必填 | 参数描述 |
259| ------ | -------- |---- | ------- |
260| type   | string | 是 | 代表订阅扩展Ability发生异步注册回调。 |
261| callback   | Callback\<UIExtensionProxy\> | 是 | 订阅扩展Ability注册setReceiveDataCallback后触发的回调。 |
262
263### on('syncReceiverRegister')<sup>11+</sup>
264
265on(type: 'syncReceiverRegister', callback: Callback\<UIExtensionProxy\>): void;
266
267用于在双方建立连接成功后,组件使用方订阅被拉起的Ability发生同步注册的场景。
268
269**系统能力:** SystemCapability.ArkUI.ArkUI.Full
270
271**参数:**
272
273| 参数名  | 参数类型 |必填 | 参数描述 |
274| ------ | -------- |---- | ------- |
275| type   | string | 是 | 订阅扩展Ability发生同步注册回调。 |
276| callback   | Callback\<UIExtensionProxy\> | 是 | 扩展Ability注册setReceiveDataForResultCallback后触发的回调。 |
277
278### off('asyncReceiverRegister')<sup>11+</sup>
279
280off(type: 'asyncReceiverRegister', callback?: Callback\<UIExtensionProxy\>): void
281
282用于在双方建立连接成功后,组件使用方取消订阅被拉起的Ability发生异步注册的场景。
283
284**系统能力:** SystemCapability.ArkUI.ArkUI.Full
285
286**参数:**
287
288| 参数名  | 参数类型 | 必填 | 参数描述 |
289| ------ | -------- | ----- | ------- |
290| type   | string | 是 | 取消订阅扩展Ability发生异步注册回调。 |
291| callback | Callback\<UIExtensionProxy\> | 否 | 为空代表取消订阅所有扩展Ability异步注册后触发回调。<br> 非空代表取消订阅异步对应回调。 |
292
293### off('syncReceiverRegister')<sup>11+</sup>
294
295off(type: 'syncReceiverRegister', callback?: Callback\<UIExtensionProxy\>): void
296
297用于在双方建立连接成功后,组件使用方取消订阅被拉起的Ability发生同步注册的场景。
298
299**系统能力:** SystemCapability.ArkUI.ArkUI.Full
300
301**参数:**
302
303| 参数名  | 参数类型 | 必填 | 参数描述 |
304| ------ | -------- | ----- | ------- |
305| type   | string | 是 | 取消订阅扩展Ability发生同步注册回调。 |
306| callback | Callback\<UIExtensionProxy\> | 否 | 为空代表取消订阅所有扩展Ability同步注册后触发回调<br> 非空代表取消订阅同步对应回调。 |
307
308## 示例
309
310### 示例1 (加载UIExtension)
311
312UIExtensionComponent组件使用分为使用方和提供方。本示例仅展示组件使用的方法和扩展的Ability,实际运行需在设备中安装bundleName为"com.example.newdemo",abilityName为"UIExtensionProvider"的Ability扩展。
313
314**组件使用方**
315
316使用方入口界面Index.ets内容如下:
317```ts
318import { ComponentContent } from '@kit.ArkUI';
319class Params {
320}
321@Builder
322function LoadingBuilder(params: Params) {
323  Column() {
324   LoadingProgress()
325      .color(Color.Blue)
326  }
327}
328@Builder
329function AreaChangePlaceholderBuilder(params: Params) {
330  Column() {
331  }
332  .width('100%')
333  .height('100%')
334  .backgroundColor(Color.Orange)
335}
336@Entry
337@Component
338struct Second {
339  @State message1: string = 'Hello World 1'
340  @State message2: string = 'Hello World 2'
341  @State message3: string = 'Hello World 3'
342  @State visible: Visibility = Visibility.Hidden
343  @State wid: number = 300
344  @State hei: number = 300
345  @State windowStrategy: WindowModeFollowStrategy = WindowModeFollowStrategy.FOLLOW_UI_EXTENSION_ABILITY_WINDOW_MODE;
346  private proxy: UIExtensionProxy | null = null;
347  private initPlaceholder = new ComponentContent(this.getUIContext(), wrapBuilder(LoadingBuilder), new Params);
348  private areaChangePlaceholder = new ComponentContent(this.getUIContext(), wrapBuilder(AreaChangePlaceholderBuilder), new Params);
349
350
351  build() {
352    Row() {
353      Column() {
354        Text(this.message1).fontSize(30)
355        Text(this.message2).fontSize(30)
356        Text(this.message3).fontSize(30)
357        UIExtensionComponent({
358          bundleName : "com.example.newdemo",
359          abilityName: "UIExtensionProvider",
360          parameters: {
361            "ability.want.params.uiExtensionType": "sys/commonUI"
362          }},
363          {
364            placeholder: this.initPlaceholder,
365            areaChangePlaceholder: {
366              "FOLD_TO_EXPAND" : this.areaChangePlaceholder,
367            },
368            windowModeFollowStrategy: this.windowStrategy
369          })
370          .width(this.wid)
371          .height(this.hei)
372          .border({width: 5, color: Color.Blue})
373          .onReceive((data) => {
374            console.info('Lee onReceive, for test')
375            this.message3 = JSON.stringify(data['data'])
376          })
377          .onTerminated((info) => {
378            console.info('onTerminated: code =' + info.code + ', want = ' + JSON.stringify(info.want));
379          })
380          .onRemoteReady((proxy) => {
381            console.info('onRemoteReady, for test')
382            this.proxy = proxy
383
384            this.proxy.on("syncReceiverRegister", syncRegisterCallback1);
385
386            this.proxy.on("asyncReceiverRegister", (proxy1) => {
387              console.info("on invoke for test, type is asyncReceiverRegister");
388            });
389          })
390
391        Button("点击向UIExtensionAbility发送数据").onClick(() => {
392          if (this.proxy != undefined) {
393            this.proxy.send({data: "你好1"})
394
395            try {
396              let re = this.proxy.sendSync({data: "你好2"})
397              console.info("for test, re=" + JSON.stringify(re));
398            } catch (err) {
399              console.error(`sendSync failed for test. errCode=${err.code}, msg=${err.message}`);
400            }
401          }
402        })
403      }
404      .width('100%')
405    }
406    .height('100%')
407  }
408}
409
410function syncRegisterCallback1(proxy: UIExtensionProxy) {
411  console.info("on invoke for test, syncRegisterCallback1, type is syncReceiverRegister");
412}
413
414function syncRegisterCallback2(proxy: UIExtensionProxy) {
415  console.info("on invoke for test, syncRegisterCallback2, type is syncReceiverRegister");
416}
417```
418**组件提供方**
419
420提供方包含三个文件需要修改
421- 提供方新增扩展入口文件/src/main/ets/uiextensionability/UIExtensionProvider.ets
422```ts
423import { UIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
424
425const TAG: string = '[UIExtAbility]'
426export default class UIExtAbility extends UIExtensionAbility {
427
428  onCreate() {
429    console.log(TAG, `UIExtAbility onCreate`)
430  }
431
432  onForeground() {
433    console.log(TAG, `UIExtAbility onForeground`)
434  }
435
436  onBackground() {
437    console.log(TAG, `UIExtAbility onBackground`)
438  }
439
440  onDestroy() {
441    console.log(TAG, `UIExtAbility onDestroy`)
442  }
443
444  onSessionCreate(want: Want, session: UIExtensionContentSession) {
445    console.log(TAG, `UIExtAbility onSessionCreate, want: ${JSON.stringify(want)}`)
446    let param: Record<string, UIExtensionContentSession> = {
447      'session': session
448    };
449    let storage: LocalStorage = new LocalStorage(param);
450    session.loadContent('pages/extension', storage);
451  }
452
453  onSessionDestroy(session: UIExtensionContentSession) {
454    console.log(TAG, `UIExtAbility onSessionDestroy`)
455  }
456}
457```
458
459- 提供方扩展Ability入口页面文件/src/main/ets/pages/extension.ets
460```ts
461import { UIExtensionContentSession } from '@kit.AbilityKit';
462
463let storage = new LocalStorage()
464AppStorage.setOrCreate('message', 'UIExtensionAbility')
465
466@Entry(storage)
467@Component
468struct Extension {
469  @StorageLink('message') storageLink: string = '';
470  private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session');
471  pathStack: NavPathStack = new NavPathStack()
472
473  @Builder
474  PageMap(name: string) {
475    if (name === "hello") {
476      pageOneTmp()
477    }
478  }
479
480  onPageShow() {
481    if (this.session != undefined) {
482      this.session.setReceiveDataCallback((data)=> {
483        this.storageLink = JSON.stringify(data)
484        console.info("invoke for test, handle callback set by setReceiveDataCallback successfully");
485      })
486
487      this.session.setReceiveDataForResultCallback(func1)
488    }
489  }
490
491  build() {
492    Navigation(this.pathStack) {
493      Row() {
494        Column() {
495          Text(this.storageLink)
496            .fontSize(20)
497            .fontWeight(FontWeight.Bold)
498          Button("点击向Component发送数据").onClick(()=>{
499            if (this.session != undefined) {
500              this.session.sendData({"data": 543321})
501              console.info('send 543321, for test')
502            }
503          })
504          Button("terminate").onClick(()=> {
505            if (this.session != undefined) {
506              this.session.terminateSelf();
507            }
508            storage.clear()
509          })
510          Button("terminate with result").onClick(()=>{
511            if (this.session != undefined) {
512              this.session.terminateSelfWithResult({
513                resultCode: 0,
514                want: {
515                  bundleName: "myBundleName",
516                  parameters: { "result": 123456 }
517                }
518              })
519            }
520            storage.clear()
521          })
522
523          Button("点击跳转").onClick(()=> {
524            this.pathStack.pushPath({ name: "hello"})
525          })
526        }
527      }
528      .height('100%')
529    }.navDestination(this.PageMap)
530    .mode(NavigationMode.Stack)
531  }
532}
533
534// pageOne
535@Component
536export struct pageOneTmp {
537  pathStack: NavPathStack = new NavPathStack()
538
539  build() {
540    NavDestination() {
541      Column() {
542        Text("Hello World")
543      }.width('100%').height('100%')
544    }.title("pageOne")
545    .onBackPressed(() => {
546      const popDestinationInfo = this.pathStack.pop() // 弹出路由栈栈顶元素
547      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
548      return true
549    })
550    .onReady((context: NavDestinationContext) => {
551      this.pathStack = context.pathStack
552    })
553  }
554}
555
556function func1(data: Record<string, Object>): Record<string, Object> {
557  let linkToMsg: SubscribedAbstractProperty<string> = AppStorage.link('message');
558  linkToMsg.set(JSON.stringify(data))
559  console.info("invoke for test, handle callback set by setReceiveDataForResultCallback successfully");
560  return data;
561}
562
563```
564
565- 提供方扩展Ability, module配置文件/src/main/module.json5添加对应配置
566```json
567{
568    "name": "UIExtensionProvider",
569    "srcEntry": "./ets/uiextensionability/UIExtensionProvider.ets",
570    "description": "1",
571    "label": "$string:EntryAbility_label",
572    "type": "sys/commonUI",
573    "exported": true,
574}
575```
576
577### 示例2 (UEC内外部同时响应滚动时隔离处理)
578
579本示例展示了当UIExtensionComponent组件使用方和扩展的Ability同时使用[Scroll](ts-container-scroll.md)容器的场景,通过对UIExtensionComponent设置手势拦截处理,实现当UIExtensionComponent内部滚动时,外部组件不响应滚动。
580
581手势使用方式:
582组件内部滚动:手指在组件内部进行滚动操作;
583组件外部滚动:拖动外部滚动条进行滚动。
584
585实际运行时需先在设备中安装bundleName为"com.example.newdemo",abilityName为"UIExtensionProvider"的Ability扩展。
586
587提供方扩展入口文件UIExtensionProvider.ets与[示例1](#示例1-加载uiextension)扩展入口文件UIExtensionProvider.ets代码一致。
588
589提供方扩展Ability, module配置文件与[示例1](#示例1-加载uiextension)扩展module配置文件module.json5代码一致。
590
591- 使用方组件使用示例:
592```ts
593@Entry
594@Component
595struct Second {
596  @State message1: string = 'Hello World 1'
597  @State message2: string = 'Hello World 2'
598  @State message3: string = 'Hello World 3'
599  @State visible: Visibility = Visibility.Hidden
600  @State wid: number = 300
601  @State hei: number = 300
602  private scroller: Scroller = new Scroller();
603  private arr: number[] = [0, 1, 2, 3, 4, 5, 6]
604
605  build() {
606    Column() {
607      // 可滚动的容器组件
608      Scroll(this.scroller) {
609        Column() {
610          Text(this.message1).fontSize(30)
611          Text(this.message2).fontSize(30)
612          Text(this.message3).fontSize(30)
613
614          // 重复设置组件,构造滚动内容
615          ForEach(this.arr, (item: number) => {
616            UIExtensionComponent({
617                bundleName: "com.example.newdemo",
618                abilityName: "UIExtensionProvider",
619                parameters: {
620                  "ability.want.params.uiExtensionType": "sys/commonUI"
621                }
622              })
623              .width(this.wid)
624              .height(this.hei)
625               // 设置手势拦截,UEC外部组件不响应滚动
626              .gesture(PanGesture().onActionStart(() => {
627                console.info('UIExtensionComponent PanGesture onAction')
628              }))
629              .border({ width: 5, color: Color.Blue })
630              .onReceive((data) => {
631                console.info('Lee onReceive, for test')
632                this.message3 = JSON.stringify(data['data'])
633              })
634              .onTerminated((info) => {
635                console.info('onTerminated: code =' + info.code + ', want = ' + JSON.stringify(info.want));
636              })
637              .onRemoteReady((proxy) => {
638                console.info('onRemoteReady, for test')
639              })
640            }, (item: string) => item)
641        }
642        .width('100%')
643      }
644      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
645      .scrollBar(BarState.On) // 滚动条常驻显示
646      .scrollBarColor(Color.Gray) // 滚动条颜色
647      .scrollBarWidth(10) // 滚动条宽度
648      .friction(0.6)
649      .edgeEffect(EdgeEffect.None)
650      .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
651        console.info(xOffset + ' ' + yOffset)
652      })
653      .onScrollEdge((side: Edge) => {
654        console.info('To the edge')
655      })
656      .onScrollStop(() => {
657        console.info('Scroll Stop')
658      })
659    }
660    .height('100%')
661  }
662}
663```
664
665- 提供方扩展Ability入口页面文件extension.ets
666```ts
667@Entry
668@Component
669struct Extension {
670  @StorageLink('message') storageLink: string = '';
671  private scroller: Scroller = new Scroller();
672  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8]
673
674  build() {
675    Column() {
676      // 可滚动的容器组件
677      Scroll(this.scroller) {
678        Column() {
679          Text('Test demo')
680            .fontSize(20)
681            .fontWeight(FontWeight.Bold)
682          // 重复设置组件,构造滚动内容
683          ForEach(this.arr, (item: number) => {
684            Text(item.toString())
685              .width('90%')
686              .height(150)
687              .backgroundColor(Color.Pink)
688              .borderRadius(15)
689              .fontSize(16)
690              .textAlign(TextAlign.Center)
691              .margin({ top: 10 })
692          }, (item: string) => item)
693        }
694      }
695
696    }
697    .height('100%')
698  }
699}
700```
701