HarmonyOS鸿蒙Next中Web组件点击全屏播放导致页面布局错乱的问题如何处理

HarmonyOS鸿蒙Next中Web组件点击全屏播放导致页面布局错乱的问题如何处理

【问题现象】

  • Web组件引用三方H5页面加载的视频,当点击视频全屏,视频区域会被组件占用,导致布局错乱如图。通过原生的方法来解决布局错乱的问题,达到如图3的效果。

点击放大 点击放大 点击放大

图1 退出全屏模式 图2 全屏模式(布局错乱) 图3 全屏模式(布局正常)

【背景知识】

  • Web组件可以实现页面加载的功能。页面加载数据来源有三种常用场景:包括加载网络页面、加载本地页面、加载HTML格式的富文本数据,其中加载H5的方法为Web({src:‘www.example.com’, controller: this.controller })。查看更多关于Web加载页面Web加载页面的方法。
  • Web组件可以通过onFullScreenEnter和onFullScreenExit回调来监听是否点击全屏的按键,其中onFullScreenEnter代表Web组件进入全屏模式,onFullScreenExit代表Web组件退出全屏模式,在这两个监听事件中,可以针对具体的业务场景,修改某些全局变量(例如组件的显隐状态、组件的margin属性等),达到全屏和非全屏显示不同的页面效果。查看更多关于Web组件的事件使用方法。
  • 开发者可以通过显隐控制的方式来实现组件在显示和隐藏间的切换,显隐控制visibility是ArkUI应用开发框架提供的组件通用属性之一,开发者可以通过设定组件属性visibility不同的属性值,进而控制组件的显隐状态。visibility属性值及其描述如下:
名称 描述
Visible 组件状态为可见
Hidden 组件状态为不可见,但参与布局、进行占位
None 组件状态为不可见,不参与布局、不进行占位

查看更多有关于显隐控制visibility的用法。

【定位思路】

(1)当使用Web组件时,在点击全屏触发onFullScreenEnter回调的时候,视频区域会被Web之外的组件占用,导致页面布局异常,对于Stack布局,可以考虑修改Web组件的margin属性来规避;

(2)但是如果是Column布局,Web只是Column中的一部分,就需要每个组件的高度都设置成全局变量,切换全屏模式时,对各个组件的height进行变换,比较麻烦,此时采用Visibility.Visible和Visibility.None来控制组件的显隐状态更为简便。

【解决方案】

(1)通过Stack布局,当视频进入全屏时,修改Web组件的margin属性为0,退出全屏时,恢复margin属性初始值。

代码示例如下:

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct ShortWebPage {
  controller: webview.WebviewController = new webview.WebviewController()
  CONSTANT_HEIGHT = 100; // Web组件的高度默认值设置为100
  @State marginTop: number = this.CONSTANT_HEIGHT; // 自定义组件的margin高度属性为全局变量

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Text('TextTextTextText')
        .width('100%')
        .height(this.CONSTANT_HEIGHT)
        .backgroundColor('#e1dede')
      Web({
        src: "http://www.example.com", // 示例网址
        controller: this.controller
      })
        .onFullScreenEnter((event) => {
          console.log("onFullScreenEnter...")
          // 当全屏的时候,web组件的margin属性高度设置为0
          this.marginTop = 0;
        })
        .onFullScreenExit(() => {
          console.log("onFullScreenExit...")
          // 当退出全屏的时候,web组件的margin属性高度恢复初始值
          this.marginTop = this.CONSTANT_HEIGHT;
        })
        .width('100%')
        .height("100%")
        .zIndex(10) // Web组件margin属性高度呈动态变化
        .margin({ top: this.marginTop })
        .zoomAccess(true)
    }
    .width('100%')
    .height('100%')
  }
}

(2)如果是Column布局下,可以采取Visibility.Visible和Visibility.None来控制组件的显隐状态。

代码示例如下:

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct ShortWebPage {
  controller: webview.WebviewController = new webview.WebviewController()
  CONSTANT_HEIGHT = 100;
  @State marginTop: number = this.CONSTANT_HEIGHT;
  @State isVisible: boolean = true; // 自定义标志位isVisible,来控制是否需要显示组件

  build() {
    Column() {
      Text('TextTextTextText')
        .width('100%')
        .height(this.CONSTANT_HEIGHT)
        .backgroundColor('#e1dede') // 当isVisible标志位为true的时候,组件状态为可见,否则组件状态为不可见,不参与布局、不进行占位
        .visibility(this.isVisible ? Visibility.Visible :
        Visibility.None)
      Web({
        src: "http://www.example.com", // 示例网址
        controller: this.controller
      })
        .onFullScreenEnter((event) => {
          console.log("onFullScreenEnter...")
          // 当全屏的时候,isVisible标志位为false,组件状态为不可见,不参与布局、不进行占位
          this.isVisible = false;
        })
        .onFullScreenExit(() => {
          console.log("onFullScreenExit...")
          // 当退出全屏的时候,isVisible标志位为true,组件状态为可见
          this.isVisible = true;
        })
        .width('100%')
        .height("100%")
        .zIndex(10)
        .zoomAccess(true)
    }.width('100%').height('100%')
  }
}

通过以上方法实现后,运行程序,可以看到点击全屏,视频正常显示,无布局错乱情况,详见上图3。

【总结】

当Web组件与其他组件在一个容器的场景下,点击Web组件中调用的H5视频中的全屏会发生布局错乱的情况,此时可以通过修改一些布局属性,让视频充满全屏幕,达到全屏效果,或者根据实际业务场景对Web之外的组件进行显隐操作。


更多关于HarmonyOS鸿蒙Next中Web组件点击全屏播放导致页面布局错乱的问题如何处理的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中Web组件点击全屏播放导致页面布局错乱的问题如何处理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


通过修改Web组件的margin属性或使用Visibility.Visible和Visibility.None控制组件的显隐状态

通过修改Web组件的margin属性或使用Visibility.VisibleVisibility.None控制组件的显隐状态,可以解决HarmonyOS鸿蒙Next中Web组件点击全屏播放导致页面布局错乱的问题。具体方法如下:

1. Stack布局

在全屏时,将Web组件的margin属性设置为0,退出全屏时恢复初始值。

Stack布局示例:

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct ShortWebPage {
  controller: webview.WebviewController = new webview.WebviewController()
  CONSTANT_HEIGHT = 100;
  @State marginTop: number = this.CONSTANT_HEIGHT;

  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Text('TextTextTextText')
        .width('100%')
        .height(this.CONSTANT_HEIGHT)
        .backgroundColor('#e1dede')
      Web({
        src: "http://www.example.com",
        controller: this.controller
      })
        .onFullScreenEnter((event) => {
          this.marginTop = 0;
        })
        .onFullScreenExit(() => {
          this.marginTop = this.CONSTANT_HEIGHT;
        })
        .width('100%')
        .height("100%")
        .zIndex(10)
        .margin({ top: this.marginTop })
        .zoomAccess(true)
    }
    .width('100%')
    .height('100%')
  }
}

2. Column布局

使用Visibility.VisibleVisibility.None控制组件的显隐状态,全屏时隐藏其他组件,退出全屏时恢复显示。

Column布局示例:

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct ShortWebPage {
  controller: webview.WebviewController = new webview.WebviewController()
  CONSTANT_HEIGHT = 100;
  @State marginTop: number = this.CONSTANT_HEIGHT;
  @State isVisible: boolean = true;

  build() {
    Column() {
      Text('TextTextTextText')
        .width('100%')
        .height(this.CONSTANT_HEIGHT)
        .backgroundColor('#e1dede')
        .visibility(this.isVisible ? Visibility.Visible : Visibility.None)
      Web({
        src: "http://www.example.com",
        controller: this.controller
      })
        .onFullScreenEnter((event) => {
          this.isVisible = false;
        })
        .onFullScreenExit(() => {
          this.isVisible = true;
        })
        .width('100%')
        .height("100%")
        .zIndex(10)
        .zoomAccess(true)
    }.width('100%').height('100%')
  }
}

通过以上方法,可以解决全屏播放时页面布局错乱的问题。

回到顶部