弹窗类UI封装
游戏中存在很多调用系统UI组件进行绘制的场景,这部分UI要求绘制在游戏画面(XComponent组件)上方,同时不影响游戏的正常渲染,如游戏登录及其他弹框、webview页面、扫码页面等等,这种弹窗类UI常常需要统一的封装和控制逻辑,同时支持与页面解耦,可全局使用。
当前系统侧实现自定义弹窗有以下几种方式:
不同弹窗在使用上存在其局限性,详情可以参考如下表格中的能力支持情况:
游戏场景下,推荐使用UIContext.OverlayManager或UIContext.PromptAction实现弹窗类UI的封装,二者使用方法类似,以下以OverlayMananger为例,介绍如何封装弹窗类UI。
HarmonyOS Next提供了ComponentContent类,用于封装@Builder装饰的自定义组件函数,可以在非UI组件中实例化,从而实现解耦。同时提供OverlayManager管理类,来管理实例化后的ComponentContent的显隐,其节点层级在Page页面之上,在Dialog、Popup、Menu、BindSheet、BindContentCover和Toast等之下。将OverlayManager和ComponentContent结合即可实现弹窗类UI的统一封装和控制,整体逻辑如下图所示:
@Builder装饰器:自定义构建函数
ArkUI提供了一种轻量的UI元素复用机制@Builder,该自定义组件内部UI结构固定,仅与使用方进行数据传递。以下是一个简单的自定义构建函数的示例:
@Builder通过按引用传递的方式传入参数,才会触发动态渲染UI,并且参数只能是一个,因此UI相关的参数建议都放在一个类里面。自定义构建函数本身是没有声明周期的,因此为了实现更复杂的UI场景,可以配合@Component自定义组件使用,示例如下:
以上为通过@Builder自定义构建函数实现UI绘制的方法,在将其封装为ComponentContent实例前,还需要进行一步操作,即通过wrapBuilder模板函数将自定义构建函数转换为WrappedBuilder对象,从而实现UI组件的全局赋值和传递,wrapBuilder模板函数接口格式及示例如下:
其中WrappedBuilder<Object[]>中 Object[] 的参数类型需要和wrapBuilder参数中@Builder自定义构建函数的参数类型一致。更具体的说明请见官方文档:@Builder装饰器,wrapBuilder:封装全局@Builder
ComponentContent
ComponentContent类的构造函数如下:
-
uiContext:当前窗口下的UI上下文,无论是ComponentContent还是OverlayManager都强依赖UIContext,因此强烈建议在ability的onWindowStageCreate生命周期loadContent方法的回调中获取后保存至全局变量或单例中。
-
builder:使用wrapBuilder将@Builder自定义构建函数转换成的WrappedBuilder对象。
-
args:@Builder自定义构建函数的参数。
使用示例如下:
多内容请参考官方文档ComponentContent。
OverlayManager
OverlayManager对象需要通过UIContext.getOverlayManager方法获取,里面提供了addComponentContent、showComponentContent、 hideComponentContent等方法,来控制封装好的ComponentContent对象的显隐,整合上文提到的所有代码后,以下为通过OverlayManager打开某个弹窗的代码示例:
多内容请参考官方文档OverlayManager。
常见问题
@Component装饰的自定义组件无法触发onPageShow、onPageHide生命周期,需要在在结构体里做一些其他的配置,以实现上述三个常用的生命周期函数。ArkUI的组件可见区域变化事件onVisibleAreaChange,提供了判断组件是否完全或部分显示在屏幕中的能力。通过设置其ratios参数为[0.0,1.0],能够实现当前组件完全显示或完全消失在屏幕中时触发回调,在回调中绑定onPageShow和onPageHide,即可触发声明周期函数,详细代码如下:
Overlay节点下的自定义组件无法触发onBackPress生命周期(UIContext.PromptAction创建的弹窗能够响应,无需关注此问题),需要在Page页面的onBackPress生命周期中注册关闭和销毁ComponentContent的逻辑,以下是封装OverlayMananger管理方法的单例及onBackPress配置示例:
原文链接: 华为开发者文章
更多问题可关注:
鸿蒙游戏官方网站:已有游戏移植-鸿蒙游戏-华为开发者联盟
公开课:华为开发者学堂