目录

元服务中如何监听屏幕尺寸变化

问题现象

折叠屏幕后如何实时获取当前正在展示的屏幕尺寸?

背景知识

解决方案

通过窗口的on('windowSizeChange')方法实现对窗口尺寸变化的监听,并把宽度值通过AppStorage来传递。

  1. 在onWindowStageCreate中使用windowClass.on监听尺寸变化获取窗口宽度。
    import { ConfigurationConstant, UIAbility } from '@kit.AbilityKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    import { window } from '@kit.ArkUI';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    const DOMAIN = 0x0000;
    
    export default class EntryAbility extends UIAbility {
      onCreate(): void {
        this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
      }
    
      onDestroy(): void {
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
      }
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        let windowClass: window.Window | undefined = undefined;
        try {
          window.getLastWindow(this.context, (err: BusinessError, data) => {
            const errCode: number = err.code;
            if (errCode) {
              console.error('Failed to obtain the top window. Cause: ' + err.message);
              return;
            }
            windowClass = data;
            try {
              windowClass.on('windowSizeChange', (data) => {
                AppStorage.setOrCreate('width', windowStage.getMainWindowSync().getUIContext().px2vp(data.width));
              });
            } catch (exception) {
              console.error('Failed to enable the listener for window size changes. Cause: ' + exception.message);
            }
            console.info('Succeeded in obtaining the top window. Data: ' + data.toString());
          });
        } catch (exception) {
          console.error('Failed to obtain the top window. Cause: ' + exception.message);
        }
        // Main window is created, set main page for this ability
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
    
        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.');
        });
      }
    
      onWindowStageDestroy(): void {
        // Main window is destroyed, release UI related resources
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
      }
    
      onForeground(): void {
        // Ability has brought to foreground
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
      }
    
      onBackground(): void {
        // Ability has back to background
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
      }
    };
  2. 在页面aboutToAppear用getDefaultDisplaySync获取宽度,通过@StorageLink('width')获取监听到变化的宽度。
    import display from '@ohos.display';
    
    @Entry
    @Component
    struct Index {
      @StorageLink('width') width1: number = 0;
    
      aboutToAppear(): void {
        let displayClass: display.Display | null = null;
        displayClass = display.getDefaultDisplaySync();
        this.width1 = this.getUIContext().px2vp(displayClass.width);
      }
    
      build() {
        Column() {
          Text('屏幕宽度:' + this.width1.toString())
            .fontSize(50)
            .fontWeight(FontWeight.Bold);
        }
        .height('100%')
        .width('100%');
      }
    }