如何完成挖孔屏的适配

2024-12-18 15:58:05
124次阅读
0个评论
  1. 通过setWindowLayoutFullScreen、setWindowSystemBarEnable将窗口设置为全屏,并且隐藏顶部状态栏。

onWindowStageCreate(windowStage: window.WindowStage): void {
  AppStorage.setOrCreate('context', windowStage);
  windowStage.getMainWindow((err: BusinessError, data) => {
    let errCode: number = err.code;
    // 设置窗口为全屏显示状态
    data.setWindowLayoutFullScreen(true);
    // 设置顶部状态栏为隐藏状态
    let names: Array<'status' | 'navigation'> = [];
    data.setWindowSystemBarEnable(names, (err: BusinessError) => {
      if (err.code) {
        console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err));
        return;
      }
      console.info('Succeeded in setting the system bar to be visible.');
    });
  })
  // ...
}
  1. 通过getDefaultDisplaySync、getCutoutInfo获取窗口display对象和不可用区域的边界及宽高,再使用获取到的信息进行计算偏移量实现对不可用区域的适配。 代码如下:
import { display, promptAction, window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { batteryInfo } from '@kit.BasicServicesKit';

class TextMargin {
  left: number = 0; // 状态栏左偏移量
  right: number = 0; // 状态栏右偏移量
}

@Entry
@Component
struct Index {
  @State date: Date = new Date();
  @State currentTime: string = ''; // 顶部状态栏时间
  @State boundingRect: display.Rect[] = []; // 不可用区域数据
  @State screenWidth: number = 0; // 屏幕宽度
  @State displayClass: display.Display | null = null;
  @State topTextMargin: TextMargin = { left: 0, right: 0 }; // 顶部状态栏偏移量
  @StorageLink('context') context: common.UIAbilityContext | undefined =
    AppStorage.get('context'); // 获取UIAbilityContext

  aboutToAppear(): void {
    this.displayClass = display.getDefaultDisplaySync();
    display.getDefaultDisplaySync().getCutoutInfo((err, data) => {
      if (err.code !== 0) {
        console.log('getCutoutInfo failed. error is:', JSON.stringify(err));
        return;
      }
      this.boundingRect = data.boundingRects;
      this.topTextMargin = this.getBoundingRectPosition();
    })
    // 获取小时
    let hours = this.date.getHours();
    // 获取分钟
    let minutes = this.date.getMinutes();
    // 分钟小于10在前面加0
    this.currentTime = hours.toString() + ':' + (minutes < 10 ? '0' + minutes : minutes.toString());
  }

  // 退出当前页面时将窗口重新设置成初始状态
  aboutToDisappear() {
    if (this.context !== undefined) {
      window.getLastWindow(this.context, async (err, data) => {
        if (err.code !== 0) {
          console.log('getLastWindow failed. error is:', JSON.stringify(err));
          data.setWindowSystemBarEnable(['status', 'navigation']);
          data.setWindowLayoutFullScreen(false);
        }
      })
    }
  }

  getBoundingRectPosition(): TextMargin {
    if (this.boundingRect !== null && this.displayClass !== null && this.boundingRect[0] !== undefined) {
      // 不可用区域右侧到屏幕右边界的距离:屏幕宽度减去左侧宽度和不可用区域宽度
      let boundingRectRight: number =
        this.displayClass.width - (this.boundingRect[0].left + this.boundingRect[0].width);
      // 不可用区域左侧到屏幕左边界的距离:getCutoutInfo接口可以直接获取
      let boundingRectLeft: number = this.boundingRect[0].left;
      // 部分设备不可用区域在中间时存在左右距离会有10像素以内的差距,获取到的左右距离差值绝对值小于10都按照不可用区域位于中间处理
      if (Math.abs(boundingRectLeft - boundingRectRight) <= 10) {
        return { left: 0, right: 0 };
      }
      if (boundingRectLeft > boundingRectRight) {
        // 不可用区域在右边
        return { left: 0, right: this.displayClass.width - boundingRectLeft };
      } else if (boundingRectLeft < boundingRectRight) {
        // 不可用区域在左边
        return { left: this.boundingRect[0].left + this.boundingRect[0].width, right: 0 };
      }
    }
    return { left: 0, right: 0 };
  }

  build() {
    Stack() {
      Image($r('app.media.digging_hole_screen_2048game'))
        .objectFit(ImageFit.Fill)
        .width('100%')
        .height('100%')
        .onClick(() => {
          promptAction.showToast({
            message: '该功能暂未开发',
            duration: 2000
          })
        })
      Column() {
        Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
          Text(this.currentTime) // 时间
            .fontSize(16)
            .fontColor(Color.Black)
            .fontWeight(FontWeight.Regular)
            .padding({ left: 12 })
            .margin({
              left: px2vp(this.topTextMargin.left),
              top: 14
            }) // 获取的偏移量单位为px需要进行转换
          Text(batteryInfo.batterySOC.toString() + '%')// 电池电量
            .fontSize(16)
            .fontColor(Color.Black)
            .fontWeight(FontWeight.Regular)
            .padding({ right: 16 })
            .margin({
              right: px2vp(this.topTextMargin.right),
              top: 14
            }) // 获取的偏移量单位为px需要进行转换
        }
        .width('100%')
      }
      .width('100%')
    }
    .width('100%')
    .height('100%')
    .alignContent(Alignment.TopStart)
  }
}
收藏00

登录 后评论。没有帐号? 注册 一个。