HarmonyOS鸿蒙Next中悬浮窗不支持手机,画中画不支持静态页面,我们需要实现游戏内展示攻略小窗的功能,还有什么方案吗?
HarmonyOS鸿蒙Next中悬浮窗不支持手机,画中画不支持静态页面,我们需要实现游戏内展示攻略小窗的功能,还有什么方案吗? 【问题描述】:悬浮窗不支持手机,画中画不支持静态页面,我们需要实现游戏内展示攻略小窗的功能,还有什么方案吗?
【问题现象】:咨询问题,悬浮窗的权限仅PC/2in1设备应用可申请,画中画又仅支持视频这种动态的方式展示,无法满足需求,我们的攻略窗口需要像悬浮窗一样在应用进入后台后仍然可以展示,自定义弹窗也无法满足,所以想问问还有什么方案可以实现我们的需求。
开发者你好,画中画支持显示静态画面,内容需要自行设计,参考官网接口示例:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-pipwindow#pipwindowcreate
create并startpip 具体代码如下:
import { BusinessError } from '@kit.BasicServicesKit';
import { BuilderNode, FrameNode, NodeController, PiPWindow, UIContext } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
class Params {
text: string = '';
constructor(text: string) {
this.text = text;
}
}
// 可以通过@Builder装饰器实现布局构建
@Builder
function buildText(params: Params) {
Column() {
Text(params.text)
.fontSize(20)
.fontColor(Color.Red)
}
.width('100%') // 宽度方向充满画中画窗口
.height('100%') // 高度方向充满画中画窗口
}
// 可通过继承NodeController实现自定义UI控制器
class TextNodeController extends NodeController {
private message: string;
private textNode: BuilderNode<[Params]> | null = null;
constructor(message: string) {
super();
this.message = message;
}
// 通过BuilderNode加载自定义布局
makeNode(context: UIContext): FrameNode | null {
this.textNode = new BuilderNode(context);
this.textNode.build(wrapBuilder<[Params]>(buildText), new Params(this.message));
return this.textNode.getFrameNode();
}
// 可自定义该方法实现布局更新
update(message: string) {
console.log(`update message: ${message}`);
if (this.textNode !== null) {
this.textNode.update(new Params(message));
}
}
}
@Entry
@Component
struct Index {
private message: string = 'createPiP';
private pipController: PiPWindow.PiPController | undefined = undefined;
private mXComponentController: XComponentController =
new XComponentController(); // 应使用该mXComponentController初始化XComponent: XComponent( {id: 'video', type: 'surface', controller: mXComponentController} ),保证XComponent的内容可以被迁移到画中画窗口。
private nodeController: TextNodeController = new TextNodeController('this is custom UI');
private navId: string = 'page_1'; // 假设当前页面的导航id为page_1,详见PiPConfiguration定义,具体导航名称自行定义。
private contentWidth: number = 800; // 假设当前内容宽度800px。
private contentHeight: number = 600; // 假设当前内容高度600px。
private para: Record<string, number> = { 'PropA': 47 };
private localStorage: LocalStorage = new LocalStorage(this.para);
private res: boolean = this.localStorage.setOrCreate('PropB', 121);
private defaultWindowSizeType: number = 1; // 指定画中画第一次拉起窗口为小窗口。
private config: PiPWindow.PiPConfiguration = {
context: this.getUIContext().getHostContext() as Context,
componentController: this.mXComponentController,
// navigationId: this.navId,
templateType: PiPWindow.PiPTemplateType.VIDEO_CALL,
contentWidth: this.contentWidth,
contentHeight: this.contentHeight,
// controlGroups: [PiPWindow.VideoPlayControlGroup.VIDEO_PREVIOUS_NEXT],
customUIController: this.nodeController, // 可选,如果需要在画中画显示内容上方展示自定义UI,可设置该参数。
localStorage: this.localStorage, // 可选,如果需要跟踪主窗实例,可设置此参数。
// defaultWindowSizeType: this.defaultWindowSizeType, // 可选,如果需要配置默认启动窗口档位,可设置此参数。
};
createAndStartPiP() {
let promise: Promise<PiPWindow.PiPController> = PiPWindow.create(this.config);
promise.then((data: PiPWindow.PiPController) => {
this.pipController = data;
let promise: Promise<void> = this.pipController.startPiP();
promise.then(() => {
console.info(`Succeeded in starting pip.`);
}).catch((err: BusinessError) => {
console.error(`Failed to start pip. Cause:${err.code}, message:${err.message}`);
});
console.info(`Succeeded in creating pip controller. Data:${data}`);
}).catch((err: BusinessError) => {
console.error(`Failed to create pip controller. Cause:${err.code}, message:${err.message}`);
});
}
//仅用于功能测试,实际开发过程中按功能需求设计组件
build() {
RelativeContainer() {
Button(this.message)
.onClick(() => {
this.createAndStartPiP();
})
}
}
}
更多关于HarmonyOS鸿蒙Next中悬浮窗不支持手机,画中画不支持静态页面,我们需要实现游戏内展示攻略小窗的功能,还有什么方案吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在鸿蒙Next中,可通过Stage模型下的UIExtensionAbility组件实现应用内悬浮窗功能。该组件允许创建独立于主窗口的UI组件,并支持交互。对于游戏内攻略展示,可考虑将攻略内容封装为独立的UIExtensionAbility组件,通过主应用调用并管理其显示状态与位置。
针对游戏内展示攻略小窗的需求,在HarmonyOS Next当前的能力框架下,确实存在限制。除了已排除的悬浮窗(仅限PC/2in1)和画中画(仅限视频播放),可重点评估以下两种技术方案:
-
使用全屏沉浸式窗口(Full Window)结合透明背景与触摸穿透
- 可以创建一个全屏的透明窗口覆盖在游戏界面上,内部嵌入攻略内容(如Web组件或自定义UI)。
- 通过设置窗口属性实现局部区域透明(仅显示攻略面板),并将非面板区域的触摸事件传递给下层游戏应用。
- 此方案需申请
ohos.permission.SYSTEM_FLOAT_WINDOW权限(但实际以全屏窗口形式运行),并精细控制布局与事件交互。
-
利用ArkUI的模态转场(Modal Transition)或弹窗(CustomDialogController)进行增强
- 虽然标准弹窗在应用退后台时会关闭,但可通过
window模块保持前台运行状态,并结合modifier设置半持久化显示。 - 在游戏场景中,将攻略界面设计为应用内的一个独立页面,通过模态窗口形式弹出,同时调整窗口属性(如位置、大小、透明度)模拟小窗效果。
- 需注意管理应用前后台状态时的生命周期,确保攻略窗口在游戏切换时能正确隐藏或恢复。
- 虽然标准弹窗在应用退后台时会关闭,但可通过
关键考量点:
- 方案1更接近悬浮窗体验,但需处理窗口层级、事件透传及功耗优化。
- 方案2依赖应用自身保持活跃,适合攻略与游戏强关联的场景。
- 两种方案均需在
module.json5中声明所需权限与窗口能力,并充分测试不同设备上的兼容性。
建议根据攻略内容的交互复杂度与持久化显示要求进行技术选型,并参考ArkUI开发文档的窗口管理章节进行实现。


