如何解决HarmonyOS鸿蒙Next中Web组件设置透明背景失效问题
如何解决HarmonyOS鸿蒙Next中Web组件设置透明背景失效问题
【问题现象】
在Web组件中,通过router跳转到PageA,再次跳转到PageB,PageA与PageB只有半屏,并且设置了页面的半透明状态,但是透明部分的背景不是上一个页面,而是桌面。
- 预期效果: 跳转后页面的透明部分是上一个页面。
- 实际效果: 跳转后页面的透明部分是桌面,如下图:
问题代码如下:
Index.ets
import { router } from '@kit.ArkUI';
[@Entry](/user/Entry)
@Component
struct Index {
@State message: string = 'Index';
build() {
Column() {
Button(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
}).onClick(()=>{
router.pushUrl({url:"pages/PageA"})
})
}.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.backgroundColor(Color.White)
.height('100%')
.width('100%')
}
}
PageA.ets
import { router } from '@kit.ArkUI';
[@Entry](/user/Entry)
@Component
struct PageA {
@State message: string = 'Page A';
build() {
Column() {
Row(){
Button(this.message)
.id('Page A')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
}).onClick(()=>{
router.pushUrl({url:"pages/PageB"})
})
}.width("100%").height("50%")
.backgroundColor(Color.White)
.borderRadius(16)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
}
.justifyContent(FlexAlign.End)
.alignItems(HorizontalAlign.Center)
.height('100%')
.width('100%')
}
}
由于PageB代码与PageA高度类似,仅仅是弹框高度的区别,在此省略代码部分。
【背景知识】
- Navigation组件(推荐):适用于模块内和跨模块的路由切换,通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。
- Router模块(不推荐):通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。
- Router切换Navigation:原先使用Router的,建议切换成Navigation使用。
Router与Navigation的能力对比:
业务场景 | Navigation | Router |
---|---|---|
一多能力 | 支持,Auto模式自适应单栏跟双栏显示 | 不支持 |
跳转指定页面 | pushPath & pushDestination | pushUrl & pushNameRoute |
跳转HSP中页面 | 支持 | 支持 |
跳转HAR中页面 | 支持 | 支持 |
跳转传参 | 支持 | 支持 |
获取指定页面参数 | 支持 | 不支持 |
传参类型 | 传参为对象形式 | 传参为对象形式,对象中暂不支持方法变量 |
跳转结果回调 | 支持 | 支持 |
跳转单例页面 | 支持 | 支持 |
页面返回 | 支持 | 支持 |
页面返回传参 | 支持 | 支持 |
返回指定路由 | 支持 | 支持 |
页面返回弹窗 | 支持,通过路由拦截实现 | showAlertBeforeBackPage |
路由替换 | replacePath & replacePathByName | replaceUrl & replaceNameRoute |
路由栈清理 | clear | clear |
清理指定路由 | removeByIndexes & removeByName | 不支持 |
转场动画 | 支持 | 支持 |
自定义转场动画 | 支持 | 支持,动画类型受限 |
屏蔽转场动画 | 支持全局和单次 | 支持 设置pageTransition方法duration为0 |
geometryTransition共享元素动画 | 支持(NavDestination之间共享) | 不支持 |
页面生命周期监听 | UIObserver.on(‘navDestinationUpdate’) | UIObserver.on(‘routerPageUpdate’) |
获取页面栈对象 | 支持 | 不支持 |
路由拦截 | 支持通过setInercption做路由拦截 | 不支持 |
路由栈信息查询 | 支持 | getState() & getLength() |
路由栈move操作 | moveToTop & moveIndexToTop | 不支持 |
沉浸式页面 | 支持 | 不支持,需通过window配置 |
设置页面标题栏(titlebar)和工具栏(toolbar) | 支持 | 不支持 |
模态嵌套路由 | 支持 | 不支持 |
【定位思路】
背景知识中,简单描述了Router和Navigation的区别,可以看出Router有非常大的局限性,Router配合@Entry的路由方式很难实现一些复杂场景的功能,如:页面间传递不可序列化的页面参数、复杂动效互动场景的实现、模态互动场景、灵活的让开发者灵活管控页面的加载和销毁、一多分栏等能力,这些能力都需要使用Navigation实现。
考虑上述Navigation的优势,以及为保证体验一致性,跳转页面场景推荐使用Navigation。
【解决方案】
根据定位思路,应通过Navigation实现页面跳转。
作为子页面的根容器,用于显示Navigation的内容区NavDestination的NavDestinationMode.DIALOG属性。
EntryAbility.ets
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
AppStorage.setOrCreate("windowStage", windowStage);
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
PageA.ets
import window from '@ohos.window';
[@Entry](/user/Entry)
@Component
struct PageA{
@State message: string = 'Page A';
aboutToAppear() {
window.findWindow("subWindowA").setWindowBackgroundColor("# 32ffffff") // 设置子窗口背景透明
}
onBackPress() { // 关闭子窗口
window.findWindow("subWindowA").destroyWindow().then((res) => {
console.log("destroyWindow success")
}).catch(() => {
console.log("destroyWindow fail")
})
return true
}
build() {
Column() {
Row() {
Button(this.message)
.id('Page A')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
let windowStage_: window.WindowStage = AppStorage.get("windowStage") as window.WindowStage;
windowStage_.createSubWindow("subWindowB", (err, win) => { // 创建透明子窗口并打开
win.setUIContent('pages/PageB');
win.showWindow();
})
})
}
.width("100%")
.height("50%")
.backgroundColor(Color.Pink)
.borderRadius(16)
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Center)
}
.justifyContent(FlexAlign.End)
.alignItems(HorizontalAlign.Center)
.height('100%')
.width('100%')
}
}
同样,因为PageB的代码与PageA类似,在此省略代码部分。
效果如图:
更多关于如何解决HarmonyOS鸿蒙Next中Web组件设置透明背景失效问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于如何解决HarmonyOS鸿蒙Next中Web组件设置透明背景失效问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,Web组件设置透明背景失效的问题
在HarmonyOS鸿蒙Next中,Web组件设置透明背景失效的问题可以通过使用Navigation组件来解决。具体步骤如下:
1. 使用Navigation组件
替换原有的Router跳转方式,使用Navigation组件进行页面跳转。
2. 设置子窗口背景透明
在PageA的aboutToAppear
方法中,通过以下代码设置子窗口背景透明:
window.findWindow("subWindowA").setWindowBackgroundColor("#32ffffff")
3. 创建透明子窗口
在PageA的onClick
事件中,使用以下代码创建并显示透明子窗口:
windowStage_.createSubWindow("subWindowB", (err, win) => {
win.setUIContent('pages/PageB');
win.showWindow();
})
通过以上步骤,可以实现跳转后页面的透明部分显示上一个页面,而不是桌面。