当前位置: 首页 > news >正文

harmony OS NEXT-沉浸式布局实现笔记

harmony OS NEXT-沉浸式布局实现笔记

沉浸式布局核心原理

产生白边问题的原因

区域类型分辨率安全区偏移量系统组件
状态栏1280*60pxTOP: 60vp电池、信号、时间等
手势条区域1280*120pxBOTTOM: 48vp返回手势指示条

方法一:窗口全局全屏 + 安全区动态适配

1. 启用全屏模式

// entryability/EntryAbility.ts
import window from '@ohos.window';

export default class EntryAbility extends Ability {
  async onWindowStageCreate(windowStage: window.WindowStage) {
    try {
      const win = await windowStage.getMainWindow();
      await win.setWindowLayoutFullScreen(true); // 启用全屏布局
      this.setupAvoidAreaListeners(win); // 安全区变化监听
    } catch (err) {
      console.error('全屏模式设置失败:', err);
    }
  }

  private setupAvoidAreaListeners(win: window.Window) {
    win.on('avoidAreaChange', (area: window.AvoidArea) => {
      AppStorage.setOrCreate<AvoidAreaModel>('avoidArea', 
        new AvoidAreaModel(area.topRect, area.bottomRect));
    });
  }
}

2. 安全区数据模型

// model/AvoidAreaModel.ts
export class AvoidAreaModel {
  topHeight: number = 0; // VP单位
  bottomHeight: number = 0;

  constructor(topRect: rectangle.Rect, bottomRect: rectangle.Rect) {
    this.topHeight = px2vp(topRect.height);
    this.bottomHeight = px2vp(bottomRect.height);
  }
}

3. UI层安全区适配组件

// components/SafeAreaContainer.ets
@Component
struct SafeAreaContainer {
  @StorageLink('avoidArea') avoidArea: AvoidAreaModel = new AvoidAreaModel();

  build() {
    Column() {
      // 自定义内容通过slot插入
      Slot()
    }
    .padding({ 
      top: this.avoidArea.topHeight,
      bottom: this.avoidArea.bottomHeight 
    })
    .backgroundColor(Color.Transparent)
    .onAppear(() => {
      this.checkAvoidAreaValidity();
    })
  }

  private checkAvoidAreaValidity() {
    if (this.avoidArea.topHeight === 0) {
      console.warn('安全区高度未正确初始化,请检查window监听');
    }
  }
}


方法二:组件级区域控制(推荐方案)

1. 整合安全区功能的装饰器

// decorators/WithSafeArea.ts
export function WithSafeArea<T extends Object>(WrappedComponent: new () => T) {
  @Component
  struct WrapperComponent {
    @State avoidArea: AvoidAreaModel = AppStorage.get('avoidArea');

    async aboutToAppear() {
      this.updateAvoidArea(); // 初次加载获取当前安全区
    }

    private async updateAvoidArea() {
      try {
        const win = await window.getTopWindow();
        const area = await win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
        this.avoidArea = new AvoidAreaModel(area.topRect, area.bottomRect);
      } catch (error) {
        console.error('安全区获取失败:', error);
      }
    }

    build() {
      Column() {
        WrappedComponent()
      }
      .padding({
        top: this.avoidArea.topHeight,
        bottom: this.avoidArea.bottomHeight
      })
    }
  }
  return WrapperComponent;
}

2. 使用示例

@Entry
@WithSafeArea
struct HomePage {
  build() {
    Column() {
      Text('主内容区域')
        .fontSize(20)
        .fontColor(Color.White)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FF409EFF')
  }
}



方案对比与最佳实践

对比维度全局窗口方案组件级方案
性能消耗中等(全局监听)低(按需加载)
代码侵入性高(需修改Ability)低(装饰器模式)
动态更新支持自动响应需手动刷新
多窗口场景支持部分支持完全支持
推荐应用场景全App沉浸式风格统一特定页面定制化需求

开发建议:

  1. 在API version ≥ 9时优先使用window.getWindowAvoidArea接口

  2. 涉及横竖屏切换时添加防抖处理:

    let resizeTimer: number = 0;win.on('windowSizeChange', () => {  clearTimeout(resizeTimer);  resizeTimer = setTimeout(() => this.updateAvoidArea(), 300);});
    
  3. 在原子化服务场景中应与enterFullScreen方法结合使用

相关文章:

  • CSS层叠顺序
  • 算法竞赛备赛——【数据结构】并查集
  • Hexo + Fluid博客实现自定义图标
  • Verilog HDL 100道面试题及参考答案
  • 目前市场上,好用的校招系统是哪个?
  • 我与数学建模之启程
  • C/C++网络编程【1】----- 大纲
  • 【深度视觉】第十八章:YOLO系列1
  • Jetpack Room 使用与原理解析
  • Vue2 vs Vue3 生命周期全面对比:created 的进化与革新!!!
  • String数据结构之验证码实战
  • Unity3D仿星露谷物语开发32之地面属性决定角色动作
  • 【Django】教程-5-ModelForm增删改查+规则校验【正则+钩子函数】
  • 数据库表省市区分析
  • Kubernetes可视化面板——KubePi(Kubernetes Visualization Panel - kubepi)
  • Android BottomNavigationView 完全自定义指南:图标、文字颜色与选中状态
  • Outlook客户端无法连接到服务器,添加账户显示“无网络连接,请检查你的网络设置,然后重试。[2603]”
  • 优秀的 React 入门开源项目推荐
  • Redis 源码硬核解析系列专题 - 结语:从源码看Redis的设计哲学
  • Meta Llama 3:开启大语言模型新纪元
  • 做网站工资待遇如何/上海关键词优化公司bwyseo
  • 石家庄网站建设电话咨询/互联网广告行业分析
  • 网站开发建设及推广合同/竞价交易规则
  • 泰安最新通告今天/百度seo营销推广
  • 做网站联系/惠州seo计费管理
  • 网站在工信部备案如何做/搜狗竞价推广效果怎么样