写点什么

【每日学点 HarmonyOS Next 知识】自定义对象传参、页面生命周期、自定义弹窗、路由打开对话框,网络图片

作者:轻口味
  • 2025-03-15
    北京
  • 本文字数:3391 字

    阅读完需:约 11 分钟

【每日学点HarmonyOS Next知识】自定义对象传参、页面生命周期、自定义弹窗、路由打开对话框,网络图片

1、HarmonyOS 如何方便的自定义对象传参数?

如何方便的自定义对象传参数


在 ArkTS 语法中对于字典是有约束的,使用 map 只能通过 set 的方式在 ArkTS 中,对象的属性名不能为数字或字符串。例外:ArkTS 支持属性名为字符串字面量和枚举中的字符串值。通过属性名访问类的属性,通过数值索引访问数组元素。ArkTS 中:


class X {  public name: string = ''}let x: X = { name: 'x' };console.log(x.name);
let y = ['a', 'b', 'c'];console.log(y[2]);
复制代码


在需要通过非标识符(即不同类型的 key)获取数据的场景中,使用 Map<Object, some_type>。


let z = new Map<Object, string>();z.set('name', '1');z.set(2, '2');console.log(z.get('name'));console.log(z.get(2));
enum Test { A = 'aaa', B = 'bbb'}
let obj: Record<string, number> = { [Test.A]: 1, // 枚举中的字符串值 [Test.B]: 2, // 枚举中的字符串值 ['value']: 3 // 字符串字面量}
复制代码

2、HarmonyOS 除了 route 可以获取到 page 相关信息,HarmonyOS 页面中有 title 的概念么?

应用的 UI 页面可以由一个或者多个自定义组件组成,@Entry 装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个 @Entry,只有被 @Entry 装饰的组件才可以调用页面的生命周期,所以说并没有 title 这个概念。参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-page-custom-components-lifecycle-V5


在开始之前,我们先明确自定义组件和页面的关系:


  • 自定义组件:@Component 装饰的 UI 单元,可以组合多个系统组件实现 UI 的复用,可以调用组件的生命周期。

  • 页面:即应用的 UI 页面。可以由一个或者多个自定义组件组成,@Entry 装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个 @Entry。只有被 @Entry 装饰的组件才可以调用页面的生命周期。


页面生命周期,即被 @Entry 装饰的组件生命周期,提供以下生命周期接口:


  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。

  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。

  • onBackPress:当用户点击返回按钮时触发。


组件生命周期,即一般用 @Component 装饰的自定义组件的生命周期,提供以下生命周期接口:


  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其 build()函数之前执行。

  • onDidBuild:组件 build()函数执行完成之后回调该接口,开发者可以在这个阶段进行埋点数据上报等不影响实际 UI 的功能。不建议在 onDidBuild 函数中更改状态变量、使用 animateTo 等功能,这可能会导致不稳定的 UI 表现。

  • aboutToDisappear:aboutToDisappear 函数在自定义组件析构销毁之前执行。不允许在 aboutToDisappear 函数中改变状态变量,特别是 @Link 变量的修改可能会导致应用程序行为不稳定。


生命周期流程如下图所示,下图展示的是被 @Entry 装饰的组件(页面)生命周期。

【每日学点 HarmonyOS Next 知识】自定义对象传参、页面生命周期、自定义弹窗、路由打开对话框,网络图片

3、HarmonyOS 弹窗的样式能否支持自定义?

需要实现一个下拉弹窗的功能,弹窗在宽度上需要为屏幕的宽度。自定义弹窗、popup、菜单的弹窗宽度最大化,距离屏幕也会有一定间距。弹窗的样式是否可以自定义?


自定义弹窗 (CustomDialog)中的 customStyle 属性置为 true 时,弹窗宽度可以达到最大化示例如下:


// xxx.etsimport { ResizeDirection } from '@kit.TestKit'
@CustomDialogstruct CustomDialogExampleTwo { controllerTwo?: CustomDialogController build() { Column() { Text('我是第二个弹窗') .fontSize(30) .height(100) Button('点我关闭第二个弹窗') .onClick(() => { if (this.controllerTwo != undefined) { this.controllerTwo.close() } }) .margin(20) } }}@CustomDialogstruct CustomDialogExample { @Link textValue: string @Link inputValue: string dialogControllerTwo: CustomDialogController | null = new CustomDialogController({ builder: CustomDialogExampleTwo(), alignment: DialogAlignment.Bottom, offset: { dx: 0, dy: -25 } }) controller?: CustomDialogController // 若尝试在CustomDialog中传入多个其他的Controller,以实现在CustomDialog中打开另一个或另一些CustomDialog,那么此处需要将指向自己的controller放在所有controller的后面 cancel: () => void = () => { } confirm: () => void = () => { }
build() { Column() { Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 }) TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%') .onChange((value: string) => { this.textValue = value }) Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 }) Flex({ justifyContent: FlexAlign.SpaceAround }) { Button('cancel') .onClick(() => { if (this.controller != undefined) { this.controller.close() this.cancel() } }).backgroundColor(0xffffff).fontColor(Color.Black) Button('confirm') .onClick(() => { if (this.controller != undefined) { this.inputValue = this.textValue this.controller.close() this.confirm() } }).backgroundColor(0xffffff).fontColor(Color.Red) }.margin({ bottom: 10 })
Button('点我打开第二个弹窗') .onClick(() => { if (this.dialogControllerTwo != null) { this.dialogControllerTwo.open() } }) .margin(20) }.borderRadius(10).backgroundColor(0x300aff) // 如果需要使用border属性或cornerRadius属性,请和borderRadius属性一起使用。 }}@Entry@Componentstruct CustomDialogUser { @State textValue: string = '' @State inputValue: string = 'click me' dialogController: CustomDialogController | null = new CustomDialogController({ builder: CustomDialogExample({ cancel: ()=> { this.onCancel() }, confirm: ()=> { this.onAccept() }, textValue: $textValue, inputValue: $inputValue }), cancel: this.exitApp, autoCancel: true, alignment: DialogAlignment.Bottom, offset: { dx: 0, dy: -20 }, gridCount: 4, customStyle: true, cornerRadius: 10, })
// 在自定义组件即将析构销毁时将dialogControlle置空 aboutToDisappear() { this.dialogController = null // 将dialogController置空 }
onCancel() { console.info('Callback when the first button is clicked') }
onAccept() { console.info('Callback when the second button is clicked') }
exitApp() { console.info('Click the callback in the blank area') } build() { Column() { Button(this.inputValue) .onClick(() => { if (this.dialogController != null) { this.dialogController.open() } }).backgroundColor(0x317aff) }.width('100%').margin({ top: 5 }) }}
复制代码

4、HarmonyOS CustomDialog 通过路由打开页面出现的问题?

在 page1 中打开一个 dialog,然后 dialog 里有个按钮跳转到 page2,但是很奇怪 page2 不是覆盖上来,而是插入在 page1 跟 dialog 之间,dialog 在最顶层


参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5

5、HarmonyOS 如何访问一个在线的图片?

Image 组件可以加在网络在线图片,需要需要申请权限 ohos.permission.INTERNET


参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/image-V5


发布于: 刚刚阅读数: 5
用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017-10-17 加入

Android、音视频、AI相关领域从业者。 欢迎加我微信wodekouwei拉您进InfoQ音视频沟通群 邮箱:qingkouwei@gmail.com

评论

发布
暂无评论
【每日学点HarmonyOS Next知识】自定义对象传参、页面生命周期、自定义弹窗、路由打开对话框,网络图片_HarmonyOS_轻口味_InfoQ写作社区