鸿蒙面试题:如何在鸿蒙ArkTs中进行全局弹框?

本文介绍了如何在鸿蒙系统中创建全屏自定义视图,通过创建自定义窗口和使用LocalStorage传递参数,以及利用HDEntryKit作为通用组件库。作者分享了实现步骤和代码实例,适用于iOS开发者转向鸿蒙的技术过渡。
摘要由CSDN通过智能技术生成

背景

刚接触鸿蒙开发不久,从iOS转过来的,经常会遇到在一个公共的类里,会想要给当前window上添加一个全屏的自定义视图,那在鸿蒙中应该如何实现这一个效果呢?

这里介绍一下我自己想到的实现方式,不一定是最优解,大家有其他更好的方式或者问题,欢迎指正。

代码是基于鸿蒙next和模拟器

思路

在鸿蒙中,虽然可以通过下面的系统方法获取到window,但是目前我不知道如何像iOS一样,在其上添加自定义的组件。所以,在研究了系统的window之后,想到是否可以直接弹出一个全屏的window,然后在这个自定义的window上,添加我们的自定义组件。类似于iOS的三方库SwiftEntryKit

import { window } from '@kit.ArkUI'
function findWindow(name: string): Window;

实现步骤

  1. 通过调用createWindow函数,创建一个自定义的window,并设置windowType枚举为 TYPE_DIALOG,这个是一个API10之后有的类型。
  2. 通过调用loadContent(path: string, storage: LocalStorage, callback: AsyncCallback<void>): void创建一个指定的页面作为这个window的根视图,我们后面自己的自定义弹框组件,都是加载到这个页面中。第二个参数storage也很重要,因为通过该方法指定了页面,但是无法将自定义的参数直接传入到页面中,所以通过LocalStorage进行中转传值。
  3. 在需要进行传值的属性中,非常重要的是一个entry?: CustomBuilder自定义组件的属性,因为我们毕竟是要封装一个通用的类,去支持你传入任意的自定义视图。这里有个非常重要的点:在class中传入的这个属性,是一个代码块,里面是我们自定义的组件代码,但是我们无法在page中,直接去执行这个代码块,来获取到相应的布局。这里其实还需要在page的代码中新增一个属性@BuilderParam entryView: CustomBuilder,这个应该很熟悉,就是如果我们是直接初始化一个包含这个属性的组件时,就可以直接传入一个@Builder function()自定义组件,并且内部可以直接使用。那我们这里需要做的就是,在page的aboutToAppear中,将我们传入的参数,赋值给这个页面声明的属性,这样就可以在布局中去加载这个布局了。
  4. 传入到页面中的参数,还可以包含布局/动画等参数,这里只实现了布局,后续可以继续完善动画相关方法
  5. 最后在传入这个布局代码的时候,如果有自定义的点击事件,需要注意this的绑定当前调用方。

代码

公共模块:

 
import { window } from '@kit.ArkUI'
import { common } from '@kit.AbilityKit'

export class HDEntryKit {
  static display(use: EKAttributes) {
    HDWindowProvider.instance().display(use)
  }

  static dismiss(complete?: (() => void)) {
    HDWindowProvider.instance().dismiss(complete)
  }
}

class HDWindowProvider {
  private static windowProvider: HDWindowProvider
  context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  windowName: string = "HDEntryWindow"

  static instance() {
    if (!HDWindowProvider.windowProvider) {
      HDWindowProvider.windowProvider = new HDWindowProvider();
    }
    return HDWindowProvider.windowProvider;
  }

  display(use: EKAttributes) {
    let windowClass: window.Window
    window.createWindow({
      name: this.windowName,
      windowType: window.WindowType.TYPE_DIALOG,
      ctx: this.context
    }, (err, data) => {
      if (err.code == 0) {
        windowClass = data
        windowClass.setWindowLayoutFullScreen(true)
        let bundleName = this.context.applicationInfo.name
        let page = `@bundle:${bundleName}/uicomponents/ets/HDEntryKit/HDEntryPage`
        let storage: LocalStorage = new LocalStorage()
        storage.setOrCreate('use', use)
        windowClass.loadContent(page, storage, err => {
          if (err.code == 0) {
            windowClass.setWindowBackgroundColor(use.backgroundColor?.toString())
          }
        })
        windowClass.showWindow(() => {
        })
      }
    })
  }

  dismiss(complete?: (() => void)) {
    window.findWindow(this.windowName).destroyWindow((err, e) => {
      if (err.code == 0 && complete) {
        complete()
      }
    })
  }
}

export class Size {
  width: Length | null = null
  height: Length | null = null
  margin: Length | Padding = 0
}

export class EKAttributes {
  name?: string
  entry?: CustomBuilder
  position: FlexAlign = FlexAlign.Center
  backgroundColor: ResourceColor = "#99000000"
  displayDuration: number = 1000
  size: Size = new Size()
}

import { EKAttributes, HDEntryKit } from './HDEntryKit'

let storage = LocalStorage.getShared()
@Entry(storage)
@Component
struct HDEntryPage {
  @BuilderParam entryView: CustomBuilder
  @LocalStorageProp('use') use: EKAttributes = new EKAttributes()

  build() {
    Column() {
      Row() {
        Column() {
          if (this.entryView) {
            this.entryView()
          }
        }
        .width('100%')
        .onClick(e => {})
      }
      .width(this.use.size.width)
      .height(this.use.size.height)
      .margin(this.use.size.margin)
      .backgroundColor(Color.Blue)
    }
    .width('100%')
    .height('100%')
    .justifyContent(this.use.position)
    .onClick(event => {
      HDEntryKit.dismiss()
    })
  }

  aboutToAppear(): void {
    this.entryView = this.use.entry
  }

调用方:

/// 弹框的配置
let use = new EKAttributes()
use.size.height = 100
use.size.margin = 20
use.position = FlexAlign.End
use.entry = this.text.bind(this)
HDEntryKit.display(use)

/// 自定义的弹框组件
@Builder text() {
  Row() {
    Text("123")
      .backgroundColor('#ff0000')
      .onClick(() => {
        this.test()
      })
  }
  .width('100%')
  .justifyContent(FlexAlign.Start)
}

/// 弹框组件中的页面跳转事件
test() {
  HDEntryKit.dismiss(() => {
    let bundleName = this.context.applicationInfo.name
    let loginPage = `@bundle:${bundleName}/login/ets/pages/LoginRegisterPage`
    router.pushUrl({url: loginPage})
  })
}

注意

通过自定义window方法弹出页面后,如果在调用router.push,则是默认在这个自定义的window进行页面跳转,当你销毁这个window的时候,打开的页面都会被关闭。所以,在demo里是在window销毁后,再进行页面跳转


最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料

 获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

 有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值