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