文档管理中心
FAQ多设备场景平板常见问题平板横屏状态下,页面两侧出现大量黑边

平板横屏状态下,页面两侧出现大量黑边

问题现象

在平板横屏状态下,播放视频两侧出现了大量黑边。

背景知识

  • XComponent:提供用于图形绘制和媒体数据写入的Surface,XComponent负责将其嵌入到视图中,支持应用自定义Surface位置和大小。具体指南请参考自定义渲染 (XComponent)文档
  • on('windowSizeChange'):可监听窗口尺寸的变化,当窗口尺寸变化时,应用可通过改变自身的布局以适配不同的窗口尺寸。

问题定位

  1. 使用DevEco Testing查看页面布局,发现该页面使用了XComponent组件。

  2. 根据布局查看,发现XComponent组件的宽高属性没有铺满整个屏幕。

  3. 检查代码中是否设置了固定宽高,是否没有通过on('windowSizeChange')接口动态调整布局。示例代码如下:
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
      XComponent({
        id: 'xComponentId',
        type: XComponentType.SURFACE,
        controller: this.myXComponentController
      })
        .width(this.getUIContext().px2vp(this.windowWidth))
        .height(this.getUIContext().px2vp(this.windowHeight))
    }

分析结论

XComponent组件设置了固定宽高,没有通过on('windowSizeChange')获取到当前窗口最新尺寸,动态调整页面布局,导致两侧出现大量黑边。

修改建议

  1. 在EntryAbility.ets中,通过on('windowSizeChange')监听窗口尺寸的变化,存入AppStorage中。
    onWindowStageCreate(windowStage: window.WindowStage): void {
      // Main window is created, set main page for this ability
      hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
      windowStage.getMainWindow().then((windowClass) => {
        // 获取窗口尺寸,存入AppStorage
        AppStorage.setOrCreate('windowWidth', windowClass.getWindowProperties().windowRect.width);
        AppStorage.setOrCreate('windowHeight', windowClass.getWindowProperties().windowRect.height);
        // 监听窗口尺寸变化
        windowClass.on('windowSizeChange', (windowSize) => {
          AppStorage.setOrCreate('windowWidth', windowSize.width);
          AppStorage.setOrCreate('windowHeight', windowSize.height);
        });
      });
      windowStage.loadContent('pages/Index', (err) => {
        if (err.code) {
          hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
          return;
        }
        hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
      });
    }
  2. 页面通过@StorageLink装饰的数据在窗口尺寸发生变化时会引起组件的重新渲染,根据最新的窗口尺寸动态调整页面布局,确保页面铺满整个屏幕。
    import { media } from '@kit.MediaKit';
    
    @Entry
    @Component
    struct XComponentIndex {
      private avPlayer: media.AVPlayer | null = null; // AVPlayer实例
      private surfaceId: string = ''; // 播放窗口SurfaceID
      // 初始化参数,这里会初始化为AppStorage中存储的值
      @StorageLink('windowWidth') windowWidth: number | undefined = AppStorage.get('windowWidth');
      @StorageLink('windowHeight') windowHeight: number | undefined = AppStorage.get('windowHeight');
      myXComponentController: XComponentController = new XComponentController();
    
      // 初始化播放器
      async initAVPlayer() {
        try {
          // 创建AVPlayer实例
          this.avPlayer = await media.createAVPlayer();
          // 设置监听事件
          this.avPlayer.on('stateChange', async (state: string) => {
            if (state === 'initialized') {
              // 设置播放窗口
              this.avPlayer!.surfaceId = this.surfaceId;
              await this.avPlayer!.prepare();
            } else if (state === 'prepared') {
              await this.avPlayer!.play(); // 自动开始播放
            }
          });
          this.avPlayer.url = 'https://xxx.mp4'; // 替换为实际地址
        } catch (error) {
          console.error(`Player initialization failed: ${error}`);
        }
      }
    
      build() {
        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
          XComponent({
            id: 'xComponentId',
            type: XComponentType.SURFACE,
            controller: this.myXComponentController
          })
            .onLoad(async () => {
              // 获取SurfaceID并初始化播放器
              this.surfaceId = this.myXComponentController.getXComponentSurfaceId();
              this.initAVPlayer();
            })
            .width(this.getUIContext().px2vp(this.windowWidth))
            .height(this.getUIContext().px2vp(this.windowHeight));
        };
      }
    }
  3. 配置必要权限,在module.json5中添加网络访问权限。
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],
在 FAQ 中进行搜索
请输入您想要搜索的关键词