如何解决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

1 回复

更多关于如何解决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(); 
})

通过以上步骤,可以实现跳转后页面的透明部分显示上一个页面,而不是桌面。

回到顶部