鸿蒙应用沉浸式效果开发

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

沉浸式效果是提升用户体验的重要手段,通过调整状态栏、应用界面和导航条的显示效果来减少系统界面的突兀感。本文将全面介绍鸿蒙开发中实现沉浸式效果的技术方案、API使用。

一、沉浸式效果基础概念

1. 界面元素与区域划分

典型应用全屏窗口UI元素包括:

  • 状态栏:显示系统信息(时间、电量等)
  • 应用界面:主要内容展示区
  • 导航条:底部操作区域

这些区域中,状态栏和导航条通常称为避让区,避让区之外的区域称为安全区

2. 设计要素

  • UI元素避让处理:可交互元素应避开系统UI区域
  • 视觉一致性:状态栏/导航条颜色应与界面元素协调
  • 交互体验:不影响系统手势操作的同时保证内容完整展示

二、沉浸式实现方案

鸿蒙主要提供了三种实现沉浸式效果方案:

1. 窗口全屏布局方案

核心API
  • setWindowLayoutFullScreen():设置窗口全屏显示
  • getWindowAvoidArea():获取避让区域信息
  • on('avoidAreaChange'):监听避让区域变化
实现步骤
  1. 设置窗口全屏
// EntryAbility.ets
import { window } from '@kit.ArkUI';

onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.getMainWindowSync().setWindowLayoutFullScreen(true)
    .then(() => {
      console.info('设置全屏成功');
    });
}

        2. 获取避让区域:

    // 获取导航条避让区域
    const avoidArea = window.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
    const bottomHeight = avoidArea.bottomRect.height;
    
    // 获取状态栏避让区域
    const systemAvoidArea = window.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
    const topHeight = systemAvoidArea.topRect.height;

        3. 动态调整布局:

    // 监听避让区域变化
    window.on('avoidAreaChange', (data) => {
      if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
        // 更新状态栏高度
        AppStorage.setOrCreate('topRectHeight', data.area.topRect.height);
      }
    });

    2. 安全区扩展方案

    核心API
    • expandSafeArea():组件安全区扩展属性 
    实现方式
    Image($r('app.media.background'))
      .width('100%')
      .height('100%')
      .expandSafeArea(
        [SafeAreaType.SYSTEM, SafeAreaType.CUTOUT], // 扩展类型
        [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]     // 扩展方向
      )

    参数说明

    • SafeAreaType枚举:
      • SYSTEM:系统默认避让区
      • CUTOUT:刘海屏挖孔区
      • KEYBOARD:软键盘区域 
    • SafeAreaEdge枚举:
      • TOP:顶部
      • BOTTOM:底部
      • START:起始边
      • END:结束边 

    3. 背景色统一方案

    通过设置窗口背景色实现视觉沉浸:

    // Ability中设置
    onWindowStageCreate(windowStage: window.WindowStage) {
      windowStage.getMainWindowSync()
        .setWindowBackgroundColor('#F5F5F5'); // 与界面主色一致
    }

    三、高级功能实现

    1. 动态隐藏系统UI

    完全隐藏状态栏和导航条:

    // 需要import window from '@kit.ArkUI'
    window.getLastWindow(getContext())
      .then(win => {
        win.setWindowLayoutFullScreen(true);
        win.setWindowSystemBarEnable(['status', 'navigation'], false);
      });

    2. 状态栏文字颜色控制

    设置状态栏文字深色/浅色模式:

    window.getLastWindow(getContext())
      .then(win => {
        win.setWindowSystemBarProperties({
          statusBarContentColor: '#000000' // 黑色文字
        });
      });

    3. 分场景适配方案

    场景1:视频播放页 - 完全沉浸

    aboutToAppear(): void {
      window.getLastWindow(getContext())
        .then(win => {
          win.setWindowLayoutFullScreen(true);
          win.setWindowSystemBarEnable([], false); // 全部隐藏
        });
    }

    场景2:阅读页 - 半沉浸

    aboutToAppear(): void {
      window.getLastWindow(getContext())
        .then(win => {
          win.setWindowSystemBarProperties({
            statusBarColor: '#F5F5F5',
            navigationBarColor: '#F5F5F5',
            statusBarContentColor: '#000000'
          });
        });
    }

    四、避坑指南

    1. 常见问题解决

    问题1:刘海屏内容遮挡

    • 解决方案
    Column() {
      // 内容区
    }
    .margin({ top: $r('app.float.status_bar_height') }) // 预留状态栏高度

    问题2:键盘弹出布局错乱

    • 解决方案
    TextArea()
      .expandSafeArea([SafeAreaType.KEYBOARD], [SafeAreaEdge.BOTTOM])

    2. 性能优化建议

    1. 避免频繁更新:沉浸式设置应在onWindowStageCreateaboutToAppear中完成
    2. 使用缓存:将getWindowAvoidArea结果缓存到AppStorage
    3. 按需更新:非必要不调用setWindowLayoutFullScreen

    3. 多设备适配方案

    通过条件判断适配不同设备:

    import deviceInfo from '@ohos.deviceInfo';
    
    const deviceType = deviceInfo.deviceType;
    if (deviceType === 'phone') {
      // 手机特定适配
    } else if (deviceType === 'tablet') {
      // 平板特定适配
    }

    五、完整示例:视频播放页沉浸实现

    // VideoPlayerPage.ets
    import window from '@kit.ArkUI';
    
    @Entry
    @Component
    struct VideoPlayerPage {
      @State isFullscreen: boolean = false;
    
      build() {
        Column() {
          VideoPlayer({
            src: 'video.mp4',
            controller: this.videoController
          })
          .onClick(() => {
            this.toggleFullscreen();
          })
        }
        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
      }
    
      toggleFullscreen() {
        this.isFullscreen = !this.isFullscreen;
        window.getLastWindow(getContext())
          .then(win => {
            win.setWindowLayoutFullScreen(this.isFullscreen);
            win.setWindowSystemBarEnable(['status', 'navigation'], !this.isFullscreen);
          });
      }
    }

    实现效果

    • 点击视频进入全屏沉浸模式
    • 再次点击恢复常规显示
    • 顶部状态栏自动适配 

    六、总结与版本适配建议

    1. 方案对比

    方案适用场景优点缺点
    窗口全屏需要精确控制布局灵活度高实现复杂
    安全区扩展快速实现沉浸背景简单易用控制粒度粗
    背景色统一视觉一致性要求高性能好功能有限

    2. 版本适配

    • API 8+:支持基础沉浸式功能
    • API 12+:新增expandSafeArea等高级特性 
    • NEXT版本:推荐使用声明式安全区控制 

     

     

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值