• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# @ohos.arkui.UIContext (UIContext)(系统接口)
2
3在Stage模型中,WindowStage/Window可以通过loadContent接口加载页面并创建UI的实例,并将页面内容渲染到关联的窗口中,所以UI实例和窗口是一一关联的。一些全局的UI接口是和具体UI实例的执行上下文相关的,在当前接口调用时,通过追溯调用链跟踪到UI的上下文,来确定具体的UI实例。若在非UI页面中或者一些异步回调中调用这类接口,可能无法跟踪到当前UI的上下文,导致接口执行失败。
4
5> **说明:**
6>
7> 本模块首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
8>
9> 示例效果请以真机运行为准,当前DevEco Studio预览器不支持。
10>
11> 当前页面仅包含本模块的系统接口,其他公开接口参见[@ohos.arkui.UIContext (UIContext)](arkts-apis-uicontext-uicontext.md)。
12
13## UIContext
14
15以下API需先使用ohos.window中的[getUIContext()](arkts-apis-window-Window.md#getuicontext10)方法获取UIContext实例,再通过此实例调用对应方法。或者可以通过自定义组件内置方法[getUIContext()](arkui-ts/ts-custom-component-api.md#getuicontext)获取。本文中UIContext对象以uiContext表示。
16
17### setDynamicDimming<sup>12+<sup>
18
19setDynamicDimming(id: string, value: number): void
20
21通过该方法设置组件的压暗程度。
22
23
24> **说明:**
25>
26> 设置该属性后设置其他效果类属性会导致效果冲突。
27
28**系统能力:** SystemCapability.ArkUI.ArkUI.Full
29
30**参数:**
31
32| 参数名 | 类型 | 必填 | 说明 |
33| ------- | ------- | ------- | ------- |
34| id | string | 是 | 组件id。 |
35| value | number | 是 | 组件压暗程度取值范围[0,1], 由0到1逐渐变亮。 |
36
37**示例:**
38
39```ts
40@Entry
41@Component
42struct Index {
43  @State
44  myCount : number = 100
45
46  build() {
47    Column(){
48      Image($r('app.media.testImage')).width(500).height(800).id("test")
49    }.width("100%").height("100%").onClick(()=>{
50      this.getUIContext().setDynamicDimming("test",1)
51      this.getUIContext()?.animateTo({duration:5000 },()=>{
52        this.getUIContext().setDynamicDimming("test",0)
53      })
54    })
55  }
56}
57```
58![api-switch-overview](../apis-arkui/figures/dynamicDinning.gif)
59
60### animateToImmediately<sup>12+</sup>
61
62animateToImmediately(param: AnimateParam , event: () => void): void
63
64animateToImmediately接口允许用户通过UIContext对象,获取显式立即动画的能力。同时加载多个属性动画的情况下,使用该接口可以立即执行闭包代码中状态变化导致的过渡动效。
65
66**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
67
68**系统能力:** SystemCapability.ArkUI.ArkUI.Full
69
70**参数:**
71
72| 参数名   | 类型                                       | 必填   | 说明                                    |
73| ----- | ---------------------------------------- | ---- | ------------------------------------- |
74| param | [AnimateParam](arkui-ts/ts-explicit-animation.md#animateparam对象说明) | 是    | 设置动画效果相关参数。                           |
75| event | () => void                               | 是    | 指定显示动效的闭包函数,在闭包函数中导致的状态变化系统会自动插入过渡动画。 |
76
77**示例:**
78
79该示例实现了通过UIContext对象获取显式立即动画的能力,调用animateToImmediately接口实现参数定义的动画效果。
80
81```ts
82// xxx.ets
83@Entry
84@Component
85struct AnimateToImmediatelyExample {
86  @State widthSize: number = 250
87  @State heightSize: number = 100
88  @State opacitySize: number = 0
89  private flag: boolean = true
90  uiContext: UIContext | null | undefined = this.getUIContext();
91
92  build() {
93    Column() {
94      Column()
95        .width(this.widthSize)
96        .height(this.heightSize)
97        .backgroundColor(Color.Green)
98        .opacity(this.opacitySize)
99      Button('change size')
100        .margin(30)
101        .onClick(() => {
102          if (this.flag) {
103            this.uiContext?.animateToImmediately({
104              delay: 0,
105              duration: 1000
106            }, () => {
107              this.opacitySize = 1
108            })
109            this.uiContext?.animateTo({
110              delay: 1000,
111              duration: 1000
112            }, () => {
113              this.widthSize = 150
114              this.heightSize = 60
115            })
116          } else {
117            this.uiContext?.animateToImmediately({
118              delay: 0,
119              duration: 1000
120            }, () => {
121              this.widthSize = 250
122              this.heightSize = 100
123            })
124            this.uiContext?.animateTo({
125              delay: 1000,
126              duration: 1000
127            }, () => {
128              this.opacitySize = 0
129            })
130          }
131          this.flag = !this.flag
132        })
133    }.width('100%').margin({ top: 5 })
134  }
135}
136```
137![animateToImmediately](figures/animateToImmediately.gif)
138
139### freezeUINode<sup>18+</sup>
140
141freezeUINode(id: string, isFrozen: boolean): void
142
143通过id设置组件冻结状态,防止组件被标记为脏从而触发布局更新。
144
145**原子化服务API:** 从API version 18 开始,该接口支持在原子化服务中使用。
146
147**系统能力:** SystemCapability.ArkUI.ArkUI.Full
148
149**参数:**
150
151| 参数名     | 类型    | 必填   | 说明      |
152| --- | --- | --- | --- |
153| id | string | 是 | 组件的id。|
154| isFrozen | boolean | 是 | 是否设置冻结。<br/>true表示设置冻结,false表示设置不冻结。<br/>默认值为false。|
155
156**错误码:**
157
158以下错误码详情请参考[通用错误码](../errorcode-universal.md)。
159
160| 错误码ID | 错误信息 |
161| -------- | -------- |
162| 202 | The caller is not a system application. |
163
164```ts
165@Entry
166@Component
167struct Index {
168  @State columnWidth1: string = '100%';
169  @State currentIndex: number = 0;
170  private controller: TabsController = new TabsController();
171
172  build() {
173    Column() {
174      Tabs({
175        barPosition: BarPosition.Start,
176        index: this.currentIndex,
177        controller: this.controller
178      }) {
179        TabContent() {
180          Column()
181          .width(this.columnWidth1)
182          .height('100%')
183          .backgroundColor('#00CB87')
184        }
185        .tabBar('green')
186        .id('tab1')
187        .onWillHide(() => {
188          // id为tab1的TabContent隐藏的时候设置该节点的冻结状态为true。
189          this.getUIContext().freezeUINode('tab1', true);
190        })
191        .onWillShow(() => {
192          // id为tab1的TabContent显示的时候设置该节点的冻结状态为false。
193          this.getUIContext().freezeUINode('tab1', false);
194        })
195
196        TabContent() {
197          Column()
198          .width('100%')
199          .height('100%')
200          .backgroundColor('#007DFF')
201        }
202        .tabBar('blue')
203        .id('tab2')
204        .onWillHide(() => {
205          // id为tab2的TabContent隐藏的时候设置该节点的冻结状态为true。
206          this.getUIContext().freezeUINode('tab2', true);
207        })
208        .onWillShow(() => {
209          // 当id为tab2的TabContent显示的时候,将id为tab1的节点的冻结状态设置为true。
210          // 通过状态变量改变id为tab1的节点中Column的宽度。因该节点的冻结状态为true,标脏至TabContent时终止标记,不触发布局。
211          this.getUIContext().freezeUINode('tab1', true);
212          this.columnWidth1 = '50%';
213          // 配置延时任务。
214          setTimeout(() => {
215            // 将id为tab1的节点的冻结状态设置为false,重新触发标记和布局。
216            this.getUIContext().freezeUINode('tab1', false);
217            // 通过状态变量更新tab1内部Column节点的宽度,设置this.columnWidth1为'20%'。
218            this.columnWidth1 = '20%';
219          }, 5000)
220        })
221
222         TabContent() {
223          Column()
224          .width('100%')
225          .height('100%')
226          .backgroundColor('#FFBF00')
227        }
228        .tabBar('yellow')
229        .id('tab3')
230        .onWillHide(() => {
231          // 当id为tab3的TabContent隐藏的时候设置该节点的冻结状态为true。
232          this.getUIContext().freezeUINode('tab3', true);
233        })
234        .onWillShow(() => {
235          // id为tab3的TabContent显示的时候设置该节点的冻结状态为false。
236          this.getUIContext().freezeUINode('tab3', false);
237        })
238
239      }
240      .vertical(false)
241      .barMode(BarMode.Fixed)
242      .barWidth(360)
243      .barHeight(56)
244      .animationDuration(0)
245      .onChange((index: number) => {
246        this.currentIndex = index;
247      })
248      .width(360)
249      .height(296)
250      .margin({ top: 52 })
251      .backgroundColor('#F1F3F5')
252    }.width('100%')
253  }
254}
255```
256
257### freezeUINode<sup>18+</sup>
258
259freezeUINode(uniqueId: number, isFrozen: boolean): void
260
261通过uniqueId设置组件的冻结状态,防止组件被标记为脏从而触发布局更新。
262
263**原子化服务API:** 从API version 18 开始,该接口支持在原子化服务中使用。
264
265**系统能力:** SystemCapability.ArkUI.ArkUI.Full
266
267**参数:**
268
269| 参数名     | 类型    | 必填   | 说明      |
270| --- | --- | --- | --- |
271| uniqueId | number | 是 | 组件的uniqueId。|
272| isFrozen | boolean | 是 | 是否设置冻结。<br/>true表示设置冻结,false表示设置不冻结。<br/>默认值为false。|
273
274**错误码:**
275
276以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。
277
278| 错误码ID | 错误信息 |
279| -------- | -------- |
280| 202 | The caller is not a system application. |
281
282```ts
283@Entry
284@Component
285struct Index {
286  @State columnWidth1: string = '100%';
287  @State currentIndex: number = 0;
288  private controller: TabsController = new TabsController();
289
290  build() {
291    Column() {
292      Tabs({
293        barPosition: BarPosition.Start,
294        index: this.currentIndex,
295        controller: this.controller
296      }) {
297        TabContent() {
298          Column()
299          .width(this.columnWidth1)
300          .height('100%')
301          .backgroundColor('#00CB87')
302        }
303        .tabBar('green')
304        .id('tab1')
305        .onWillHide(() => {
306          // 通过id查询以获取对应节点的uniqueId。
307          const node = this.getUIContext().getFrameNodeById('tab1');
308          const uniqueId = node?.getUniqueId();
309          // 当id为tab1的TabContent隐藏的时候,通过uniqueId设置该节点的冻结状态为true。
310          this.getUIContext().freezeUINode(uniqueId, true);
311        })
312        .onWillShow(() => {
313          // 通过id查询以获取对应节点的uniqueId。
314          const node = this.getUIContext().getFrameNodeById('tab1');
315          const uniqueId = node?.getUniqueId();
316          // 当id为tab1的TabContent显示的时候,通过uniqueId设置该节点的冻结状态为false。
317          this.getUIContext().freezeUINode(uniqueId, false)
318        })
319
320        TabContent() {
321          Column()
322          .width('100%')
323          .height('100%')
324          .backgroundColor('#007DFF')
325        }
326        .tabBar('blue')
327        .id('tab2')
328        .onWillHide(() => {
329          // 通过id查询以获取对应节点的uniqueId。
330          const node = this.getUIContext().getFrameNodeById('tab2');
331          const uniqueId = node?.getUniqueId();
332          // 当id为tab2的TabContent隐藏的时候,通过uniqueId设置该节点的冻结状态为true。
333          this.getUIContext().freezeUINode(uniqueId, true);
334        })
335        .onWillShow(() => {
336          // 通过id查询以获取对应节点的uniqueId。
337          const node = this.getUIContext().getFrameNodeById('tab1');
338          const uniqueId = node?.getUniqueId();
339          // 当id为tab2的TabContent显示的时候,通过uniqueId设置id为tab1的节点的冻结状态为true。
340          // 通过状态变量改变id为tab1的节点内部Column节点的宽度。由于id为tab1的节点冻结状态为true,标脏至该TabContent时会终止标记,并且不会从该节点开始触发布局。
341          this.getUIContext().freezeUINode(uniqueId, true);
342          this.columnWidth1 = '50%';
343
344          // 设置延时任务。
345          setTimeout(() => {
346            // 将id为tab1的节点的冻结状态设置为false,以重新触发标记和布局。
347            this.getUIContext().freezeUINode(uniqueId, false);
348            this.columnWidth1 = '20%';
349          }, 5000)
350        })
351
352         TabContent() {
353          Column()
354          .width('100%')
355          .height('100%')
356          .backgroundColor('#FFBF00')
357        }
358        .tabBar('yellow')
359        .id('tab3')
360        .onWillHide(() => {
361          // 通过id查询以获取对应节点的uniqueId。
362          const node = this.getUIContext().getFrameNodeById('tab3');
363          const uniqueId = node?.getUniqueId();
364          // 当id为tab3的TabContent隐藏时,通过uniqueId将该节点的冻结状态设置为true。
365          this.getUIContext().freezeUINode(uniqueId, true);
366        })
367        .onWillShow(() => {
368          // 通过id查询以获取对应节点的uniqueId。
369          const node = this.getUIContext().getFrameNodeById('tab3');
370          const uniqueId = node?.getUniqueId();
371          // 当id为tab3的TabContent显示的时候,通过uniqueId设置该节点的冻结状态为false。
372          this.getUIContext().freezeUINode(uniqueId, false);
373        })
374
375      }
376      .vertical(false)
377      .barMode(BarMode.Fixed)
378      .barWidth(360)
379      .barHeight(56)
380      .animationDuration(0)
381      .onChange((index: number) => {
382        this.currentIndex = index;
383      })
384      .width(360)
385      .height(296)
386      .margin({ top: 52 })
387      .backgroundColor('#F1F3F5')
388    }.width('100%')
389  }
390}
391```
392
393### setKeyboardAppearanceConfig<sup>20+</sup>
394
395setKeyboardAppearanceConfig(uniqueId: number, config: KeyboardAppearanceConfig): void
396
397设置键盘样式,包括模糊效果和流光效果,仅在沉浸式模式下生效,沉浸式定义可参见[KeyboardAppearance枚举说明](../apis-arkui/arkui-ts/ts-text-common.md#keyboardappearance15枚举说明)。其中,流光效果依赖于模糊效果,若需启用流光效果,则需同时开启模糊效果,最终显示效果取决于输入法处理。
398
399**系统接口:** 此接口为系统接口。
400
401**系统能力:** SystemCapability.ArkUI.ArkUI.Full
402
403**参数:**
404
405| 参数名     | 类型    | 必填   | 说明      |
406| --- | --- | --- | --- |
407| uniqueId | number | 是 | 组件节点对应的UniqueId。取值范围大于等于0。 |
408| config | [KeyboardAppearanceConfig](../apis-arkui/arkui-ts/ts-text-common-sys.md#keyboardappearanceconfig20) | 是 | 键盘样式配置参数。|
409
410**错误码:**
411
412以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。
413
414| 错误码ID | 错误信息 |
415| -------- | -------- |
416| 202 | The caller is not a system application. |
417
418输入框和搜索框组件设置键盘样式使用示例:
419
420```ts
421@Entry
422@Component
423struct IMEGradient {
424  textInputController: TextInputController = new TextInputController();
425  searchController: SearchController = new SearchController();
426
427  build() {
428    Column() {
429      TextInput({ controller: this.textInputController})
430        .margin(10)
431        .border({ width: 1 })
432        .onWillAttachIME((client) => {
433          this.getUIContext().setKeyboardAppearanceConfig(client.nodeId,
434            {
435              gradientMode: KeyboardGradientMode.LINEAR_GRADIENT,
436              fluidLightMode: KeyboardFluidLightMode.BACKGROUND_FLUID_LIGHT
437            })
438        })
439        .keyboardAppearance(KeyboardAppearance.IMMERSIVE)
440
441      Search({ controller: this.searchController })
442        .margin(10)
443        .border({ width: 1 })
444        .onWillAttachIME((client) => {
445          this.getUIContext().setKeyboardAppearanceConfig(client.nodeId,
446            {
447              gradientMode: KeyboardGradientMode.LINEAR_GRADIENT,
448              fluidLightMode: KeyboardFluidLightMode.BACKGROUND_FLUID_LIGHT
449            })
450        })
451        .keyboardAppearance(KeyboardAppearance.IMMERSIVE)
452    }.width('100%').height('100%').justifyContent(FlexAlign.Center)
453  }
454}
455```
456
457## ComponentSnapshot<sup>12+</sup>
458
459以下API需先使用UIContext中的[getComponentSnapshot()](arkts-apis-uicontext-uicontext.md#getcomponentsnapshot12)方法获取ComponentSnapshot对象,再通过此实例调用对应方法。
460
461缩放、平移、旋转等图形变换属性只对被截图组件的子组件生效;对目标组件本身应用图形变换属性不生效,显示的是还是图形变换前的效果。
462
463### getWithRange<sup>20+</sup>
464getWithRange(start: NodeIdentity, end: NodeIdentity, isStartRect: boolean, options?: componentSnapshot.SnapshotOptions): Promise<image.PixelMap>;
465
466传入两个组件的ID,获取范围内的组件的截图,并通过Promise返回结果。
467
468> **说明:**
469>
470> start对应的组件和end对应的组件必须为同一棵组件树上的组件,且start对应的组件需要为end对应的组件的祖先组件。
471
472**原子化服务API:** 从API version 20开始,该接口支持在原子化服务中使用。
473
474**系统能力:** SystemCapability.ArkUI.ArkUI.Full
475
476**参数:**
477
478| 参数名  | 类型     | 必填   | 说明                                       |
479| ---- | ------ | ---- | ------- |
480| start   | [NodeIdentity](arkts-apis-uicontext-t.md#nodeidentity20) | 是    | 范围开始的组件的ID。 |
481| end   | [NodeIdentity](arkts-apis-uicontext-t.md#nodeidentity20) | 是    | 范围结束的组件的ID。 |
482| isStartRect   | boolean | 是    | 范围是否以开始组件的外接矩形为准。<br/>true表示以开始组件的外接矩形为准,false表示以结束组件的外接矩形为准。<br/>默认值为true。 |
483| options       | [componentSnapshot.SnapshotOptions](js-apis-arkui-componentSnapshot.md#snapshotoptions12)            | 否    | 截图相关的自定义参数,不支持region参数。 |
484
485**返回值:**
486
487| 类型                            | 说明       |
488| -------- | -------- |
489| image.[PixelMap](../apis-image-kit/arkts-apis-image-PixelMap.md) | 截图返回的结果。 |
490
491**错误码:**
492
493以下错误码的详细介绍请参见[通用错误码](../errorcode-universal.md)错误码和[截图错误码](errorcode-snapshot.md)。
494
495| 错误码ID  | 错误信息                |
496| ------ | ------- |
497| 202     | The caller is not a system application. |
498| 100001 | Invalid ID. |
499
500**示例:**
501
502```ts
503import { image } from '@kit.ImageKit';
504
505@Entry
506@Component
507struct SnapshotExample {
508  @State pixmap: image.PixelMap | undefined = undefined
509  build() {
510    Column() {
511      Row() {
512        Row() {
513          Row() {
514            Column() {
515              Text('Text1').id('text1')
516              Text('Text2').id('text2')
517              Row() {
518                Text('Text3').id('text3')
519              }.id('root5').backgroundColor('#E4E8F0')
520            }.width('80%').height('80%').justifyContent(FlexAlign.SpaceAround).backgroundColor('#C1D1F0').id('root4')
521          }.width('80%').height('80%').justifyContent(FlexAlign.Center).backgroundColor('#FFEEF0').id('root3')
522          .backgroundBlurStyle(BlurStyle.Thin, { colorMode: ThemeColorMode.LIGHT })
523        }.width('80%').height('80%').justifyContent(FlexAlign.Center).backgroundColor('#D5D5D5').id('root2')
524      }.width('50%').height('50%').justifyContent(FlexAlign.Center).backgroundColor('#E4E8F0').id('root1')
525      Row() {
526        Button("getWithRange")
527          .onClick(() => {
528            this.getUIContext().getComponentSnapshot().getWithRange('root2', 'root4', true)
529              .then((pixmap: image.PixelMap) => {
530                this.pixmap = pixmap
531              }).catch((err:Error) => {
532              console.error("error: " + err)
533            })
534          }).margin(10)
535      }.justifyContent(FlexAlign.SpaceAround)
536      Row() {
537        Image(this.pixmap).width(200).height(300).border({ color: Color.Black, width: 2 }).margin(5)
538      }.justifyContent(FlexAlign.SpaceAround)
539    }
540    .id('root')
541    .width('100%')
542    .height('100%')
543    .alignItems(HorizontalAlign.Center)
544  }
545}
546```
547
548![zh-cn_image_getWithRange](figures/zh-cn_image_getWithRange.gif)
549