• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ArkUI框架开发常见问题
2
3## 如何动态替换掉资源文件中的“%s”占位符
4
5适用于OpenHarmony 3.2 Beta5  API 9
6
7**问题现象**
8
9引用String资源,如何动态替换资源文件中的“%s”占位符。
10
11**解决措施**
12
13在应用中,通过`$r('app.string.xx')`的形式引用应用资源,\$r的第二个参数可用于替换%s占位符。
14
15**代码示例**
16
17```
18build() {
19  //do something
20  //引用的string资源,$r的第二个参数用于替换%s
21  Text($r('app.string.entry_desc','aaa'))
22    .fontSize(100)
23    .fontColor(Color.Black)
24  //do something
25}
26```
27
28## 自定义弹窗能否在ts文件中定义和使用
29
30适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
31
32自定义弹窗的定义和初始化需要用到属于ArkTS语法内容,必须在ets后缀文件中定义使用,不能在ts后缀文件中定义使用。
33
34**参考链接**
35
36[自定义弹窗](../reference/arkui-ts/ts-methods-custom-dialog-box.md)
37
38## 自定义弹窗中的变量如何传递给页面
39
40适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
41
42**问题现象**
43
44在自定义弹窗内定义的变量内容,在关闭弹窗或变量变化时需要及时传递给页面,可以通过何种方式传递?
45
46**解决措施**
47
48-   方式一:使用组件的状态变量传递。
49-   方式二:在初始化弹窗时,传递一个方法给自定义弹窗,在自定义弹窗中触发该方法,弹窗中变量作为方法的参数。
50-   方式三:使用AppStorage或LocalStorage方式管理页面状态,实现自定义弹窗和页面之间状态的共享。
51
52**代码示例**
53
54-   方式一:
55
56    ```
57    @CustomDialog
58    struct CustomDialog01 {
59      @Link inputValue: string
60      controller: CustomDialogController
61      build() {
62        Column() {
63          Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
64          TextInput({ placeholder: '', text: this.inputValue }).height(60).width('90%')
65            .onChange((value: string) => {
66              this.inputValue = value
67            })
68        }
69      }
70    }
71
72    @Entry
73    @Component
74    struct DialogDemo01 {
75      @State inputValue: string = 'click me'
76      dialogController: CustomDialogController = new CustomDialogController({
77        builder: CustomDialog01({
78          inputValue: $inputValue
79        })
80      })
81
82      build() {
83        Column() {
84          Button(this.inputValue)
85            .onClick(() => {
86              this.dialogController.open()
87            }).backgroundColor(0x317aff)
88        }.width('100%').margin({ top: 5 })
89      }
90    }
91
92    ```
93
94-   方式二:
95
96    ```
97    @CustomDialog
98    struct CustomDialog02 {
99      private inputValue: string
100      changeInputValue: (val: string) => void
101      controller: CustomDialogController
102      build() {
103        Column() {
104          Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
105          TextInput({ placeholder: '', text: this.inputValue }).height(60).width('90%')
106            .onChange((value: string) => {
107              this.changeInputValue(value)
108            })
109        }
110      }
111    }
112
113    @Entry
114    @Component
115    struct DialogDemo02 {
116      @State inputValue: string = 'click me'
117      dialogController: CustomDialogController = new CustomDialogController({
118        builder: CustomDialog02({
119          inputValue: this.inputValue,
120          changeInputValue: (val: string) => {
121            this.inputValue = val
122          }
123        })
124      })
125
126      build() {
127        Column() {
128          Button(this.inputValue)
129            .onClick(() => {
130              this.dialogController.open()
131            }).backgroundColor(0x317aff)
132        }.width('100%').margin({ top: 5 })
133      }
134    }
135
136    ```
137
138-   方式三:
139
140    ```
141    let storage = LocalStorage.GetShared()
142    @CustomDialog
143    struct CustomDialog03 {
144      @LocalStorageLink('inputVal')  inputValue: string = ''
145      controller: CustomDialogController
146      build() {
147        Column() {
148          Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
149          TextInput({ placeholder: '', text: this.inputValue }).height(60).width('90%')
150            .onChange((value: string) => {
151              this.inputValue = value;
152            })
153        }
154      }
155    }
156
157    @Entry(storage)
158    @Component
159    struct DialogDemo03 {
160      @LocalStorageLink('inputVal') inputValue: string = ''
161      dialogController: CustomDialogController = new CustomDialogController({
162        builder: CustomDialog03()
163      })
164
165      build() {
166        Column() {
167          Button(this.inputValue)
168            .onClick(() => {
169              this.dialogController.open()
170            }).backgroundColor(0x317aff)
171        }.width('100%').margin({ top: 5 })
172      }
173    }
174
175    ```
176
177
178## 如何获取组件的宽高
179
180适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
181
182**问题现象**
183
184组件的宽高信息用于计算布局区域大小以及偏移量等内容,如何获取宽高信息?
185
186**解决措施**
187
188-   方式一:使用组件区域变化事件onAreaChange,在组件初始化或组件尺寸发生变化时触发。
189-   方式二:在点击或触摸事件中,事件的回调信息中存在目标元素的区域信息。
190
191**参考链接**
192
193[组件区域变化事件](../reference/arkui-ts/ts-universal-component-area-change-event.md),[点击事件](../reference/arkui-ts/ts-universal-events-click.md),[触摸事件](../reference/arkui-ts/ts-universal-events-touch.md)
194
195## 如何一键清空TextInput、TextArea组件内容
196
197适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
198
199**问题现象**
200
201TextInput,TextArea组件输入多字符后,需要实现点击清空。
202
203**解决措施**
204
205将状态变量赋值给TextInput或TextArea组件的text属性,在做点击清空事件时为状态变量赋值空字符串。
206
207**代码示例**
208
209```
210struct Index {
211@State text: string = 'Hello World'
212controller: TextInputController = new TextInputController()
213  build() {
214    Row() {
215      Column() {
216        TextInput({ placeholder: 'Please input your words.', text: this.text,
217          controller:this.controller}).onChange((value) => {
218            this.text = value
219          })
220        Button("Clear TextInput").onClick(() => {
221          this.text = "";
222        })
223      }
224      .width('100%')
225    }
226    .height('100%')
227  }
228}
229```
230
231## 如何设置自定义弹窗位置
232
233适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
234
235**问题现象**
236
237自定义弹窗当前默认在窗口居中显示,当自定义弹窗需要与窗口边框对齐是需要设置自定义弹窗的对齐方式。
238
239**解决措施**
240
241初始化自定义弹窗时,通过alignment参数设置对齐方式,通过offset设置弹窗偏移量。
242
243**参考链接**
244
245[自定义弹窗](../reference/arkui-ts/ts-methods-custom-dialog-box.md)
246
247## 如何隐藏容器组件的溢出内容
248
249适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
250
251**问题现象**
252
253当容器组件内容溢出时,表现为子组件边缘超出容器组件,需要进行隐藏设置。
254
255**解决措施**
256
257将通用属性-形状裁剪clip属性设置为true,表示按照容器边缘轮廓进行裁剪。此属性默认为false,表示不进行裁剪隐藏。
258
259**参考链接**
260
261[形状裁剪](../reference/arkui-ts/ts-universal-attributes-sharp-clipping.md)
262
263
264## 自定义弹窗大小如何自适应内容
265
266适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
267
268**问题现象**
269
270当自定义弹窗中存在可变化区域大小的子组件时,弹窗大小需要跟随自适应。
271
272**解决措施**
273
274-   方式一:采用弹窗容器默认样式。在默认样式中,弹窗容器高度自适应子节点,最大可为窗口高度的90%;弹窗容器的宽度根据栅格系统自适应,不跟随子节点变化。
275-   方式二:当显示设置customStyle为true时,弹窗宽高跟随子节点内容适应。
276
277**参考链接**
278
279[自定义弹窗](../reference/arkui-ts/ts-methods-custom-dialog-box.md)
280
281## 如何理解自定义弹窗中的gridCount参数
282
283适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
284
285gridCount参数是指弹窗宽度占栅格列数的个数。系统把窗口宽等分,等分的份数即为栅格列数,不同设备栅格列数不同。比如手机屏幕密度值在320vp<=水平宽度<600vp,所以栅格列数是4,则gridCount的有效值在\[1, 4\]。
286
287注意:仅采用弹窗默认样式时设置有效。
288
289**参考链接**
290
291[自定义弹窗](../reference/arkui-ts/ts-methods-custom-dialog-box.md)
292
293## 如何去除自定义弹窗的白色背景
294
295适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
296
297**问题现象**
298
299使用自定义弹窗时,默认样式中存在白色背景。
300
301**解决措施**
302
303需要采用自定义样式来消除自定义弹窗的白色背景:
304
3051.  在初始化自定义弹窗时设置customStyle为true。
3062.  在定义弹窗时设置组件背景色backgroundColor。
307
308**参考链接**
309
310[自定义弹窗](../reference/arkui-ts/ts-methods-custom-dialog-box.md)
311
312## TextInput组件密码模式下,右边的眼睛图标能否支持自定义
313
314适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
315
316**问题现象**
317
318TextInput组件设置type为InputType.Password时,右侧出现眼睛图标,不能修改图标样式。
319
320**解决措施**
321
322当前图标不支持自定义,可使用TextInput的showPasswordIcon属性隐藏图标,使用Image组件替代控制TextInput组件的type。
323
324**参考链接**
325
326[TextInput组件](../reference/arkui-ts/ts-basic-components-textinput.md)
327
328## TextInput的onSubmit事件如何使用
329
330适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
331
332**问题现象**
333
334TextInput的onSubmit事件怎么触发,以及事件回调的参数类型代表的含义。
335
336**解决措施**
337
338onSubmit事件在外接键盘或软键盘回车时触发该回调,回调的参数为当前软键盘回车键类型。通过TextInput的enterKeyType属性可以设置输入法回车键类型,软键盘回车键样式需要输入法的支持。
339
340**参考链接**
341
342[TextInput组件](../reference/arkui-ts/ts-basic-components-textinput.md)
343
344## TextInput在聚焦时如何使光标回到起点
345
346适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
347
348**问题现象**
349
350TextInput组件在聚焦时,光标位置会自动根据触摸点位置变化,如何使得聚焦时光标固定显示在起点位置?
351
352**解决措施**
353
3541.  TextInput组件绑定onEditChange事件,该事件TextInput可进行输入时触发。
3552.  在事件回调用TextInputController.caretPosition方法设置光标位置,不过需要用到setTimeout延迟方法。
356
357**代码示例**
358
359```
360@Entry
361@Component
362struct TextInputDemo {
363  controller: TextInputController = new TextInputController()
364
365  build() {
366    Column() {
367      TextInput({ controller: this.controller })
368        .onEditChange((isEditing: boolean) => {
369          if (isEditing) {
370            setTimeout(() => {
371              this.controller.caretPosition(0)
372            }, 100)
373          }
374        })
375    }
376  }
377}
378```
379
380**参考链接**
381
382[TextInput组件](../reference/arkui-ts/ts-basic-components-textinput.md)
383
384## 如何获取组件的属性信息
385
386适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
387
388**解决措施**
389
390组件所有属性信息可通过通用属性-组件标识内getInspectorByKey获取。
391
392**参考链接**
393
394[组件标识](../reference/arkui-ts/ts-universal-attributes-component-id.md)
395
396## 如何获取可滚动组件的当前滚动偏移量
397
398适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
399
400**问题现象**
401
402可滚动组件包含List,Grid,Scroll等,在发生滚动时如何获取滚动偏移量?
403
404**解决措施**
405
4061.  可滚动组件在初始化时可设置scroller参数,绑定滚动控制器。
4072.  通过控制器的currentOffset方法可获取水平和竖直方向的滚动偏移量。
408
409**参考链接**
410
411[Scroll](../reference/arkui-ts/ts-container-scroll.md#currentoffset)
412
413## 如何实现文本竖向排列
414
415适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
416
417**问题现象**
418
419使用Text组件时,无法将文本排列方向设置为竖向排列。
420
421**解决措施**
422
423Text组件当前文本排列方向固定为横向排列,要设置为竖向排列,可将文件拆分,使用Flex容器组件装填,设置主轴方向为竖向。
424
425**代码示例**
426
427```
428@Entry
429@Component
430struct Index15 {
431  private message: string = '本文档适用于应用开发的初学者。通过构建一个简单的具有页面跳转/返回功能的应用,快速了解工程目录的主要文件,熟悉应用开发流程。';
432  build() {
433    Flex({ direction: FlexDirection.Column, wrap: FlexWrap.Wrap }) {
434      ForEach(this.message.split(''), (item, index) => {
435        Text(item)
436          .fontSize(30)
437          .flexShrink(0)
438      })
439    }
440  }
441}
442```
443
444## 如何创建Toast窗口
445
446适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
447
448**问题现象**
449
450应用做弱提示时,需要采用Toast窗口。
451
452**解决措施**
453
454可使用系统提供的@ohos.promptAction接口创建Toast窗口。
455
456**参考链接**
457
458[@ohos.promptAction \(弹窗\)](../reference/apis/js-apis-promptAction.md)
459
460## Toast弹窗是否支持自定义背景或者字体颜色
461
462适用于 OpenHarmony 3.2 Beta5 API 9 Stage模型
463
464当前版本不支持Toast弹窗自定义背景和字体颜色。
465
466**参考链接**
467
468[@ohos.promptAction \(弹窗\)](../reference/apis/js-apis-promptAction.md)
469
470## 如何将Ability的UI界面设置成透明
471
472适用于:OpenHarmony SDK 3.2,API9
473
474**问题现象**
475
476如何设置Ability的UI界面为透明
477
478**解决措施**
479
480将最上层容器组件背景色设置为透明,然后通过设置XComponent组件的opacity属性值为0.01来实现。
481
482示例:
483
484```
485build() {
486  Stack() {
487    XComponent({
488    id: 'componentId',
489    type: 'surface',
490    })
491    .width('100%')
492    .height('100%')
493    .opacity(0.01)
494    // 页面内容
495  }
496  .width('100%')
497  .height('100%')
498  .backgroundColor('rgba(255,255,255, 0)')
499}
500```
501
502## constraintSize尺寸设置不生效
503
504适用于:Openharmony 3.2 Beta5 API 9 stage模型
505
506**问题现象**
507
508constraintSize约束组件尺寸时,子组件内设置百分比宽度,例如width\('100%'\)会采用constraintSize约束中的最大宽乘百分比,导致撑开组件,看起来constraintSize设置没生效。
509
510**解决措施**
511
512可以在外层使用Scroll组件,设置constraintSize,当子组件占用空间超过设置的约束值时,会显示滚动条。
513
514## 如何将背景颜色设置为透明
515
516适用于:OpenHarmony 3.2 Beta5 API 9
517
518**解决措施**
519
520将backgroundColor设置为 '\#00000000'。
521
522## Scroll组件滚动到达不了最底部
523
524适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
525
526**问题现象**
527
528Scroll组件在未设置高度情况下,默认为窗口高度,当滚动区域外存在其他组件时,滚动底部区域会出现遮挡。
529
530**解决措施**
531
532Scroll组件需要设置Scroll高度,或者使用Flex布局限制Scroll高度。
533
534## backgroundImage如何设置CenterCrop
535
536适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
537
538**问题现象**
539
540CenterCrop是android中imageView,scaletype的设置,主要保证图片等比缩放裁剪,位置保持居中,要达到相同效果,应该怎么处理?
541
542**解决措施**
543
544可以使用通用属性backgroundImageSize\(ImageSize.cover\)和backgroundImagePosition\(Alignment.Center\)达到相同效果。
545
546## 如何自定义Video组件控制栏样式
547
548适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
549
550**解决措施**
551
5521. 通过设置属性controls为false关闭默认控制栏。
553
5542. 设置Video组件的controller。
555
5563. 通过ArkTS实现自定义的控制栏,并通过VideoController控制视频播放。
557
558**代码示例**
559
560```
561// xxx.ets
562@Entry@Componentstruct VideoCreateComponent {
563  @State videoSrc: Resource = $rawfile('video1.mp4')
564  @State previewUri: Resource = $r('app.media.poster1')
565  @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X
566  @State isAutoPlay: boolean = false
567  @State showControls: boolean = true
568  controller: VideoController = new VideoController()
569   build() {
570    Column() {
571      Video({
572        src: this.videoSrc,
573        previewUri: this.previewUri,
574        currentProgressRate: this.curRate,
575        controller: this.controller
576      }).width('100%').height(600)
577        .autoPlay(this.isAutoPlay)
578        .controls(this.showControls)
579        .onStart(() => {
580          console.info('onStart')
581        })
582        .onPause(() => {
583          console.info('onPause')
584        })
585        .onFinish(() => {
586          console.info('onFinish')
587        })
588        .onError(() => {
589          console.info('onError')
590        })
591        .onPrepared((e) => {
592          console.info('onPrepared is ' + e.duration)
593        })
594        .onSeeking((e) => {
595          console.info('onSeeking is ' + e.time)
596        })
597        .onSeeked((e) => {
598          console.info('onSeeked is ' + e.time)
599        })
600        .onUpdate((e) => {
601          console.info('onUpdate is ' + e.time)
602        })
603             Row() {
604        Button('src').onClick(() => {
605          this.videoSrc = $rawfile('video2.mp4') // 切换视频源
606        }).margin(5)
607        Button('previewUri').onClick(() => {
608          this.previewUri = $r('app.media.poster2') // 切换视频预览海报
609        }).margin(5)
610
611        Button('controls').onClick(() => {
612          this.showControls = !this.showControls // 切换是否显示视频控制栏
613        }).margin(5)
614      }
615       Row() {
616        Button('start').onClick(() => {
617          this.controller.start() // 开始播放
618        }).margin(5)
619        Button('pause').onClick(() => {
620          this.controller.pause() // 暂停播放
621        }).margin(5)
622        Button('stop').onClick(() => {
623          this.controller.stop() // 结束播放
624        }).margin(5)
625        Button('setTime').onClick(() => {
626          this.controller.setCurrentTime(10, SeekMode.Accurate) // 精准跳转到视频的10s位置
627        }).margin(5)
628      }
629       Row() {
630        Button('rate 0.75').onClick(() => {
631          this.curRate = PlaybackSpeed.Speed_Forward_0_75_X // 0.75倍速播放
632        }).margin(5)
633        Button('rate 1').onClick(() => {
634          this.curRate = PlaybackSpeed.Speed_Forward_1_00_X // 原倍速播放
635        }).margin(5)
636        Button('rate 2').onClick(() => {
637          this.curRate = PlaybackSpeed.Speed_Forward_2_00_X // 2倍速播放
638        }).margin(5)
639      }
640    }
641  }}
642```
643
644**参考链接**
645
646[Video](../reference/arkui-ts/ts-media-components-video.md#start)
647
648## 如何设置组件不同状态下的样式
649
650**问题现象**
651
652对应组件的不同状态(如无状态、按下、禁用、聚焦、点击),显示不同的样式。
653
654**解决措施**
655
656使用多态样式,在组件的StateStyles接口中,定义组件不同状态下的样式。
657
658**代码示例**
659
660```
661//xxx.ts
662@Entry
663@Component
664struct StyleExample {
665  @State isEnable: boolean = true;
666
667  @Styles pressedStyles() {
668    .backgroundColor("#ED6F21")
669    .borderRadius(10)
670    .borderStyle(BorderStyle.Dashed)
671    .borderWidth(2)
672    .borderColor('#33000000')
673    .width(120)
674    .height(30)
675    .opacity(1)
676  }
677  build() {
678    Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Center}) {
679      Text("pressed")
680        .backgroundColor('#0A59F7')
681        .borderRadius(20)
682        .borderStyle(BorderStyle.Dotted)
683        .borderWidth(2)
684        .borderColor(Color.Red)
685        .width(100)
686        .height(25)
687        .opacity(1)
688        .fontSize(14)
689        .fontColor(Color.White)
690        .stateStyles({
691          pressed: this.pressedStyles
692        })
693        .margin({
694          bottom: 20
695        })
696        .textAlign(TextAlign.Center)
697    }
698    .width(350)
699    .height(300)
700  }
701}
702```
703
704**参考链接**
705
706[多态样式](../reference/arkui-ts/ts-universal-attributes-polymorphic-style.md)
707
708## Scroll内Flex加宽高与滑动冲突
709
710适用于:OpenHarmony 3.2 Beta5 API 9 Stage模型
711
712**问题现象**
713
714当在Scroll组件中添加容器组件,并设置该容器组件的尺寸时,会破坏滚动布局。
715
716**解决措施**
717
718Scroll组件中的容器组件不设置尺寸,大小由内容撑开。
719
720## ArkTS使用position之后height不生效
721
722适用于 OpenHarmony 3.2 Beta5  API 9
723
724**问题现象**
725
726ArkTS使用position之后height不生效
727
728**解决措施**
729
730容器组件在使用position之后会脱离文本流,导致容器脱离外层容器束缚,导致height不生效,可以将外层容器换成Stack可以解决这个问题。
731
732## 焦点事件onBlur/onFocus回调无法触发
733
734适用于 OpenHarmony 3.2 Beta5  API 9
735
736**问题现象**
737
738焦点事件onBlur/onFocus回调无法触发
739
740**解决措施**
741
742焦点事件默认情况下需要外接键盘的Tab键,或方向键触发,点击触发焦点事件需要添加焦点控制属性focusOnTouch。
743
744**参考链接**
745
746[焦点控制](../reference/arkui-ts/ts-universal-attributes-focus.md)
747
748## scroll里面套一个grid,怎么禁用grid的滑动事件
749
750适用于 OpenHarmony 3.2 Beta5 API 9
751
752可以通过onScrollFrameBegin事件和scrollBy方法实现容器嵌套滚动。
753
754可参考:[容器嵌套滚动样例](../reference/arkui-ts/ts-container-scroll.md#示例2)
755
756## 如何实现一个组件不停地旋转
757
758适用于 OpenHarmony 3.2 Beta5  API 9
759
760可以通过[属性动画](../reference/arkui-ts/ts-animatorproperty.md)的方式实现。
761
762## 列表目前无法键盘上下滑动,是否能力不支持
763
764适用于 OpenHarmony 3.2 Beta5  API 9
765
766**问题现象**
767
768列表目前无法键盘上下滑动,是否能力不支持
769
770**解决措施**
771
772有以下两种方案:
773
7741.  需要在列表子项中添加focusable\(true\)进行获焦。
7752.  在每个item的外层嵌套一个可获焦组件,例如Button。
776
777## 键盘移动焦点对象按下enter,为什么不会触发点击事件?
778
779适用于 OpenHarmony 3.2 Beta5  API 9
780
781组件的内置的点击事件和开发者自定义的onClick点击事件默认会和空格键绑定,并非与enter键绑定(UX规格)
782
783## 多层组件嵌套button,如何阻止事件传递
784
785适用于 OpenHarmony 3.2 Beta5  API 9
786
787可以通过将button组件绑定参数stopPropagation来控制冒泡传递。
788
789## ArkUI如何通过代码动态创建组件
790
791适用于:OpenHarmony 3.2 Beta5 API 9
792
793**解决措施**
794
795ArkUI使用ArkTS声明式开发范式,开发者无法持有组件实例,在声明时通过渲染控制语法以及动态构建UI元素的方式,控制组件的创建。
796
797**代码示例**
798
799```
800// 条件渲染语句创建组件
801if(this.isTrue) {
802  Text("创建文本组件").fontSize(30)
803}
804// 循环渲染语句创建组件
805ForEach(this.nums,(item) => {
806  Text(item + '').fontSize(30)
807},item => JSON.stringify(item))
808```
809
810**参考链接**
811
812[渲染控制语法](../quick-start/arkts-rendering-control-overview.md)
813
814## 使用@Builder装饰器包含自定义组件的方法与普通方法的区别是什么
815
816适用于:OpenHarmony 3.2 Beta5 API 9
817
818**解决措施**
819
820@Builder装饰的方法中使用了自定义组件,那么该方法每次被调用时,对应的自定义组件均会重新创建,普通方法中不使用@builder装饰,无法容纳自定义组件。
821
822**参考链接**
823
824[@BuilderParam](../quick-start/arkts-builderparam.md)
825
826## 如何使用@BuilderParam装饰器进行组件传参
827
828适用于:OpenHarmony 3.2 Beta5 API 9
829
830**解决措施**
831
832-   不带参数
833
834    对@BuilderParam修饰的属性进行赋值时不带参数(如:content: this.specificParam),则此属性的类型需定义成无返回值的函数(如:@BuilderParam content: \(\) =\> void)。
835
836-   带参数
837
838    对@BuilderParam修饰的属性进行赋值时带参数(如:callContent: this.specificParam1\("111"\)),则此属性的类型需定义成any(如:@BuilderParam callContent: any)。
839
840
841**参考链接**
842
843[@BuilderParam](../quick-start/arkts-builderparam.md)
844
845## 如何监听数组内对象属性变化
846
847适用于:OpenHarmony 3.2 Beta5 API9
848
849**问题现象**
850
851数组内存储对象示例,需要对对象的属性变化进行监听。
852
853**解决措施**
854
855通过@Observed配合@ObjectLink装饰符实现。@Observed用于类,@ObjectLink用于变量。
856
857**代码示例**
858
8591.  在类上使用@Observed。
860
861    ```
862    @Observed
863    class ClassA {
864      public name: string
865      public c: number
866      public id: number
867
868      constructor(c: number, name: string = 'OK') {
869        this.name = name
870        this.c = c
871      }
872    }
873    ```
874
8752.  在组件变量使用@ObjectLink。
876
877    ```
878    @Component
879    struct ViewA {
880      label: string = 'ViewA1'
881      @ObjectLink a: ClassA
882
883      build() {
884        Row() {
885          Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`)
886            .onClick(() => {
887              this.a.c += 1
888            })
889        }.margin({ top: 10 })
890      }
891    }
892    ```
893
894
895**参考链接**
896
897[Observed和ObjectLink数据管理](../quick-start/arkts-observed-and-objectlink.md)
898
899## 子组件使用@Link修饰成员变量时,如何通过父组件传值
900
901适用于:OpenHarmony 3.2 Beta5 API 9
902
903**解决措施**
904
905子组件使用@Link接受父组件的值时,需要使用'\$'建立变量之间的引用关系。才能实现同步。
906
907**代码示例**
908
909@Link语义是从`$`操作符引出,即\$isPlaying是this.isPlaying内部状态的双向数据绑定。当单击子组件PlayButton中的按钮时,@Link变量更改,PlayButton与父组件中的Text和Button将同时进行刷新,同样地,当点击父组件中的Button修改this.isPlaying时,子组件PlayButton与父组件中的Text和Button也将同时刷新。
910
9111.  在父组件使用@State装饰器,传递数据使用\$符创建引用。
912
913    ```
914    @Entry
915    @Component
916    struct Player {
917      @State isPlaying: boolean = false
918      build() {
919        Column() {
920          PlayButton({ buttonPlaying: $isPlaying })
921          Text(`Player is ${this.isPlaying ? '' : 'not'} playing`).fontSize(18)
922          Button('Parent:' + this.isPlaying)
923            .margin(15)
924            .onClick(() => {
925              this.isPlaying = !this.isPlaying
926            })
927        }
928      }
929    }
930
931
932    ```
933
9342.  在子组件使用@Link接受数据。
935
936    ```
937    @Component
938    struct PlayButton {
939      @Link buttonPlaying: boolean
940
941      build() {
942        Column() {
943          Button(this.buttonPlaying ? 'pause' : 'play')
944            .margin(20)
945            .onClick(() => {
946              this.buttonPlaying = !this.buttonPlaying
947            })
948        }
949      }
950    }
951    ```
952
953
954**参考链接**
955
956[@Link](../quick-start/arkts-link.md)
957
958## 父组件如何与孙子组件进行状态同步
959
960适用于:OpenHarmony 3.2 Beta5 API 9
961
962**解决措施**
963
964-   方式一(推荐):使用@Provide和@Consume装饰器。在父组件使用@Provide,在孙子组件使用@Consume,可以实现父组件和孙子组件进行双向数据绑定。
965
966-   方式二:使用@State和@Link装饰器。在父组件使用@State,在每一层子组件(子组件和孙子组件)都使用@Link。
967
968**代码示例一**
969
9701.  父组件中使用子组件,通过Provide提供reviewVote参数,供跨级传递给孙子组件。
971
972    ```
973    @Entry
974    @Component
975    struct Father{
976      @Provide("reviewVote") reviewVotes: number = 0;
977
978      build() {
979        Column() {
980          Son()
981          Button(`Father: ${this.reviewVotes}`)
982            ...
983        }
984      }
985    }
986    ```
987
9882.  子组件中使用孙组件。
989
990    ```
991    @Component
992    struct Son{
993      build() {
994        Column() {
995          GrandSon()
996        }
997      }
998    }
999    ```
1000
10013.  孙子组件中使用Consume来接受reviewVote的参数。
1002
1003    ```
1004    @Component
1005    struct GrandSon{
1006      @Consume("reviewVote") reviewVotes: number
1007
1008      build() {
1009        Column() {
1010          Button(`GrandSon: ${this.reviewVotes}`)
1011            ...
1012        }.width('100%')
1013      }
1014    }
1015    ```
1016
1017
1018**代码示例二**
1019
10201.  父组件Father使用@State绑定数据reviewVote。
1021
1022    ```
1023    @Entry
1024    @Component
1025    struct Father {
1026      @State reviewVotes: number = 0;
1027
1028      build() {
1029        Column() {
1030          Son({reviewVotes:$reviewVotes})
1031          Button(`Father: ${this.reviewVotes}`)
1032            ...
1033        }
1034      }
1035    }
1036    ```
1037
10382.  子组件Son中使用@Link接受由父组件Father传递的参数reviewVote。
1039
1040    ```
1041    @Component
1042    struct Son{
1043      @Link reviewVotes: number;
1044      build() {
1045        Column() {
1046          Grandson({reviewVotes:$reviewVotes})
1047        }
1048      }
1049    }
1050
1051
1052    ```
1053
10543.  孙子组件GrandSon使用@Link接受由Son组件传递的参数reviewVote。
1055
1056    ```
1057    @Component
1058    struct Grandson{
1059      @Link reviewVotes: number;
1060
1061      build() {
1062        Column() {
1063          Button(`Grandson: ${this.reviewVotes}`)
1064            ...
1065        }.width('100%')
1066      }
1067    }
1068    ```
1069
1070
1071## Js如何定义callback函数
1072
1073适用于:OpenHarmony 3.2 Beta5 API 9
1074
1075**解决措施**
1076
1077定义个callback函数的样例,**示例如下:**
1078
10791.  定义回调函数
1080
1081    ```
1082    // 页面中定义个2个参数,空返回的callback函数
1083    myCallback: (a:number,b:string) => void
1084    ```
1085
10862.  在使用时进行初始化赋值
1087
1088    ```
1089    aboutToAppear() {
1090      // callback函数初始化
1091      this.myCallback= (a,b)=>{
1092        console.info(`handle myCallback a=${a},b=${b}`)
1093      }}
1094    ```
1095
1096
1097## 组件需要多次更新时如何优化性能
1098
1099适用于:OpenHarmony 3.2 Beta5 API 9
1100
1101**解决措施**
1102
1103使用状态管理模块,目前已经支持最小化更新,当数据依赖变化时,不再是重新刷新整个自定义组件,而是只更新依赖数据的视图内容。
1104
1105## 对象中函数的this如何指向外层
1106
1107适用于:Openharmony 3.2 Beta5 API 9
1108
1109**解决措施**
1110
1111通过箭头函数实现。
1112
1113**代码示例**
1114
1115```
1116const obj = {
1117  start:() => {
1118    return this.num
1119  }
1120}
1121```
1122
1123## 如何实现页面加载前从接口获取数据
1124
1125适用于:Openharmony 3.2 Beta5 API 9
1126
1127**问题现象**
1128
1129页面生命周期相关问题,在页面渲染前从接口获取数据,渲染时将数据渲染到页面上。
1130
1131**解决措施**
1132
1133在声明周期函数aboutToAppear中使用异步接口获取页面数据,数据变量使用@State修饰,数据获取完成后根据变量自动刷新页面。
1134
1135**代码示例**
1136
1137```
1138@Entry
1139@Component
1140struct Test6Page {
1141  // 数据获取成功,会自动刷新页面
1142  @State message: string = 'loading.....'
1143  aboutToAppear(){
1144    // 模拟异步接口获取数据
1145    setTimeout(()=>{
1146      this.message = 'new msg'
1147    },3000)
1148  }
1149  build() {
1150    Row() {
1151      Column() {
1152        Text(this.message)
1153          .fontSize(50)
1154          .fontWeight(FontWeight.Bold)
1155      }
1156      .width('100%')
1157    }
1158    .height('100%')
1159  }
1160}
1161```
1162
1163## Stage模型资源配置文件string.json是否支持配置占位符
1164
1165适用于:Openharmony 3.2 Beta5 API 9
1166
1167资源配置文件string.json文件本身不支持配置占位符,可以在对应的页面中通过定义变量,在实际组件使用Resources和变量拼接的方式达到实现占位符的同等效果。
1168
1169## eTS文件和ts文件的区别
1170
1171适用于:Openharmony 3.2 Beta5 API 9
1172
1173**解决措施**
1174
1175ArkTS基于兼容了TS语法,继承了TS的所有特性,当前,ArkTS在TS的基础上主要扩展了声明式UI能力,让开发者能够以更简洁、更自然的方式开发高性能应用。推荐用ArtTS开发UI相关内容,TS可以用来开发业务逻辑相关内容。
1176
1177**参考链接**
1178
1179[初识ArkTS](../quick-start/arkts-get-started.md)
1180
1181## ArkTS如何发送邮箱验证码
1182
1183适用于:Openharmony 3.2 Beta5 API 9
1184
1185**问题现象**
1186
1187ArkTS语言如何给邮箱发送邮箱验证码?用哪个接口?
1188
1189**解决措施**
1190
1191发送验证码需要请求服务端,然后服务端调用对应的短信验证码接口来实现该功能。可以通过短信服务实现相关功能。
1192
1193## 如何将传感器的数据实时显示在UI的Text中
1194
1195适用于:Openharmony 3.2 Beta5 API9
1196
1197**问题现象**
1198
1199ArkUI(ets)如何将传感器的数据实时显示在UI的Text中。
1200
1201**解决措施**
1202
1203传感器返回数据类型为double,可将double转为string,再显示在text中。
1204
1205## 如何监听屏幕旋转
1206
1207适用于:Openharmony 3.2 Beta5 API 9
1208
1209**问题现象**
1210
1211应用想监听屏幕是否进行旋转操作。
1212
1213**解决措施**
1214
1215屏幕旋转可使用媒体查询接口进行监听。
1216
1217```
1218import mediaquery from '@ohos.mediaquery'
1219let listener = mediaquery.matchMediaSync('(orientation: landscape)'); //监听横屏事件
1220function onPortrait(mediaQueryResult) {
1221  if (mediaQueryResult.matches) {
1222   // do something here
1223  } else {
1224   // do something here
1225  }
1226}
1227listener.on('change', onPortrait) // 注册回调
1228listener.off('change', onPortrait) // 去注册回调
1229```
1230
1231**参考链接**
1232
1233[媒体查询](../reference/apis/js-apis-mediaquery.md)
1234
1235## DevEco Studio 升级到最新后ForEach不能遍历全部数据
1236
1237适用于:Openharmony 3.2 Beta5 API 9
1238
1239**问题现象**
1240
1241升级DevEco Studio后,ForEach无法遍历全部数据。
1242
1243**解决措施**
1244
1245forEach\(\)功能进行了增强,其第三个参数keyGenerator如果传入参数时,需要确保数据源array中的每个元素生成的key不同,才能正常遍历。如果生成的key相同,则只能生成一个。
1246
1247该第三个参数也可以不传,系统采用默认生成方式,也可以正常遍历出全部元素。
1248
1249## 创建的单例换了页面后不生效问题
1250
1251适用于:Openharmony 3.2 Beta5 API 9
1252
1253**问题现象**
1254
1255单例只有在同一个流程中才有效,换了页面后之前的实例都全是undefined。
1256
1257**解决措施**
1258
1259对于每个Page都会生成一个js文件,定义的单例会在每个js中都生成一份,所以单例的作用范围只是Page的范围。
1260
1261如果想共享一个实例,创建范围需要提升至UIAbility或者App级别。
1262
1263## 如何将时间格式的字符串string转换为Date对象
1264
1265适用于:Openharmony 3.2 Beta5 API 9
1266
1267**解决措施**
1268
1269如果字符string满足格式“yyyy-MM-dd”格式,则可直接使用函数new Date\("yyyy-MM-dd"\)来获取对应的Date对象。
1270
1271```
1272new Date("2021-05-23");
1273new Date("2020/2/29");
1274new Date("2020-14-03");
1275new Date("14-02-2021");
1276```
1277
1278其他格式字符串可使用new Date\(year:number,month:number,day?:number,hour?:number,mintue?:number,second?:number,ms?:number\)方法来获取Date对象。
1279
1280```
1281根据参数创建日期的语法:
1282new Date(yearValue, IndexOfMonth, dayValue, hours, minutes, seconds)
1283```
1284
1285其中每一个参数换算为对应时间参数传入即可。
1286
1287-   yearValue:应符合 ISO 8061 YYYY 格式。例如 2021。如果我们以 YY 格式指定一个值,它将会被错误地接受。例如,仅将 2021 提到 21 会被认为是 1921 年而不是 2021 年。
1288-   IndexOfMonth:从索引 0 开始。因此,从 Month 值中减去 1。例如,对于 3 月,该值为 3,但 monthIndex 将为 2(即 3-1 = 2)。本月指数通常应在 0-11 范围内
1289-   dayValue:表示一个月中的某天。它应在 1-31 范围内,具体取决于一个月中的天数。例如:对于 21-05-2021,日期值为 21
1290-   hours:一天中的小时。例如 10 点。
1291-   minutes:过去一个小时的分钟数
1292-   seconds:保留超过一分钟的秒数。
1293
1294## ArkTS如何把string转为byte数组
1295
1296适用于:Openharmony 3.2 Beta5 API 9
1297
1298**解决措施**
1299
1300参考如下代码实现,示例:
1301
1302```
1303stringToArray(str:string) {
1304  var arr = [];
1305  for(var i = 0,j = str.length;i<j;++i) {
1306 arr.push(str.charCodeAt(i))
1307  }
1308  return arr;
1309}
1310```
1311
1312## ArkTS如何实现字符串编解码
1313
1314适用于:Openharmony 3.2 Beta5 API 9
1315
1316**解决措施**
1317
1318通过util工具函数模块中的TextEncoder和TextDecoder进行解码。
1319
1320**参考链接**
1321
1322[TextEncoder](../reference/apis/js-apis-util.md#textencoder)、[TextDecoder](../reference/apis/js-apis-util.md#textdecoder)
1323
1324## 如何导入和导出namespace命名空间
1325
1326适用于:Openharmony 3.2 Beta5 API 9
1327
1328**解决措施**
1329
1330通过export和import导入导出
1331
1332-   namespace导数据库出
1333
1334    ```
1335    namespace Util{
1336        export function getTime(){
1337            return Date.now()
1338        }
1339    }
1340    export default Util
1341    ```
1342
1343-   namespace导入
1344
1345    ```
1346    import Util from './util'
1347    Util.getTime()
1348    ```
1349
1350
1351## worker线程中能否进行关系型数据库的操作
1352
1353适用于:Openharmony 3.2 Beta5 API 9
1354
1355当前不支持将UI主线程中的rdb数据库对象发送给Worker线程后进行操作。Worker线程中使用rdb数据库,需要重新获取rdb数据库的对象。
1356
1357## 如何获取应用resource目录下的文件
1358
1359适用于:Openharmony 3.2 Beta5 API 9
1360
1361**解决措施**
1362
1363-   方式一:使用\$r或者\$rawfile访问。适合静态访问,程序运行时不改变资源路径。
1364-   方式二:使用ResourceManage访问。适合动态访问,程序运行时可动态改变资源路径。
1365
1366**参考链接**
1367
1368[资源访问](../quick-start/resource-categories-and-access.md)与[资源管理](../reference/apis/js-apis-resource-manager.md#getstring)
1369
1370
1371## XML格式如何转为JSON格式
1372
1373适用于:Openharmony 3.2 Beta5 API 9
1374
1375**问题现象**
1376
1377服务端返回的数据是通过base64编码后XML格式,需要转为JSON格式进行后续的处理。
1378
1379**解决措施**
1380
1381使用util工具中的base64相关接口进行解码操作,然后使用convertxml组件解析XML格式数据。
1382
1383**代码示例**
1384
1385```
1386import convertxml from '@ohos.convertxml';
1387import util from '@ohos.util';
1388
1389@Entry
1390@Component
1391struct Faq_4_31 {
1392  @State message: string = 'base64转json'
1393
1394  build() {
1395    Row() {
1396      Column() {
1397        Text(this.message)
1398          .fontSize(50)
1399          .fontWeight(FontWeight.Bold)
1400          .onClick(() => {
1401            /* 原数据,GBK编码
1402            <?xml version="1.0" encoding="GBK"?>
1403            <data>
1404            <asset_no>xxxxx</asset_no>
1405            <machine_sn>xxxx</machine_sn>
1406            <bios_id>xxxx</bios_id>
1407            <responsible_emp_name><![CDATA[xxxx]]></responsible_emp_name>
1408            <responsible_account><![CDATA[xxxx xxxx]]></responsible_account>
1409            <responsible_emp_no>xxxx</responsible_emp_no>
1410            <responsible_dept><![CDATA[xxxx]]></responsible_dept>
1411            <user_dept><![CDATA[xxxx]]></user_dept>
1412            <user_name><![CDATA[xxx]]></user_name>
1413            <cur_domain_account>xxxx</cur_domain_account>
1414            <asset_loc><![CDATA[--]]></asset_loc>
1415            <asset_loc_cur><![CDATA[]]></asset_loc_cur>
1416            <asset_type>1</asset_type>
1417            <asset_use>For Outsourcing Staff/xxxx</asset_use>
1418            <overdue_date></overdue_date>
1419            <asset_status>xxxx</asset_status>
1420            <asset_period>xxxx</asset_period>
1421            <license></license>
1422            </data>
1423             */
1424            let src = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iR0JLIj8+CjxkYXRhPgo8YXNzZXRfbm8+eHh4eHg8L2Fzc2V0X25vPgo8bWFjaGluZV9zbj54eHh4PC9tYWNoaW5lX3NuPgo8Ymlvc19pZD54eHh4PC9iaW9zX2lkPgo8cmVzcG9uc2libGVfZW1wX25hbWU+PCFbQ0RBVEFbeHh4eF1dPjwvcmVzcG9uc2libGVfZW1wX25hbWU+CjxyZXNwb25zaWJsZV9hY2NvdW50PjwhW0NEQVRBW3h4eHggeHh4eF1dPjwvcmVzcG9uc2libGVfYWNjb3VudD4KPHJlc3BvbnNpYmxlX2VtcF9ubz54eHh4PC9yZXNwb25zaWJsZV9lbXBfbm8+CjxyZXNwb25zaWJsZV9kZXB0PjwhW0NEQVRBW3h4eHhdXT48L3Jlc3BvbnNpYmxlX2RlcHQ+Cjx1c2VyX2RlcHQ+PCFbQ0RBVEFbeHh4eF1dPjwvdXNlcl9kZXB0Pgo8dXNlcl9uYW1lPjwhW0NEQVRBW3h4eF1dPjwvdXNlcl9uYW1lPgo8Y3VyX2RvbWFpbl9hY2NvdW50Pnh4eHg8L2N1cl9kb21haW5fYWNjb3VudD4KPGFzc2V0X2xvYz48IVtDREFUQVstLV1dPjwvYXNzZXRfbG9jPgo8YXNzZXRfbG9jX2N1cj48IVtDREFUQVtdXT48L2Fzc2V0X2xvY19jdXI+Cjxhc3NldF90eXBlPjE8L2Fzc2V0X3R5cGU+Cjxhc3NldF91c2U+Rm9yIE91dHNvdXJjaW5nIFN0YWZmL3h4eHg8L2Fzc2V0X3VzZT4KPG92ZXJkdWVfZGF0ZT48L292ZXJkdWVfZGF0ZT4KPGFzc2V0X3N0YXR1cz54eHh4PC9hc3NldF9zdGF0dXM+Cjxhc3NldF9wZXJpb2Q+eHh4eDwvYXNzZXRfcGVyaW9kPgo8bGljZW5zZT48L2xpY2Vuc2U+CjwvZGF0YT4='
1425            let base64 = new util.Base64Helper();
1426            // base解码
1427            let src_uint8Array = base64.decodeSync(src);
1428            // 解码为utf-8的字符串
1429            let textDecoder = util.TextDecoder.create("utf-8",{ignoreBOM: true})
1430            let src_str = textDecoder.decodeWithStream(src_uint8Array)
1431            //替换encoding字段
1432            src_str = src_str.replace("GBK","utf-8")
1433            console.log('Test src_str: ' + JSON.stringify(src_str));
1434            // 转换 xml-> json
1435            let conv = new convertxml.ConvertXML();
1436            let options = {trim : false, declarationKey:"_declaration",
1437              instructionKey : "_instruction", attributesKey : "_attributes",
1438              textKey : "_text", cdataKey:"_cdata", doctypeKey : "_doctype",
1439              commentKey : "_comment", parentKey : "_parent", typeKey : "_type",
1440              nameKey : "_name", elementsKey : "_elements"}
1441            let src_json = JSON.stringify(conv.convertToJSObject(src_str, options));
1442            console.log('Test json: ' + JSON.stringify(src_json));
1443          })
1444      }
1445      .width('100%')
1446    }
1447    .height('100%')
1448  }
1449}
1450```
1451
1452## 通过try/catch语句获取到错误码401是什么意思
1453
1454适用于:Openharmony 3.2 Beta5 API 9
1455
1456**问题原因**
1457
14581. 必选参数没有传入。
1459
14602. 参数类型错误。
1461
14623. 参数为undefined。
1463
1464**参考链接**
1465
1466[通用错误码](../reference/errorcodes/errorcode-universal.md)
1467