尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
HarmonyOS《柚兔学伴》项目实战04-沉浸式窗口与断点系统
沉浸式窗口与断点系统沉浸式体验是现代移动应用的重要设计目标——内容从状态栏底部延伸到导航栏实现全屏视觉冲击。同时HarmonyOS 支持手机、平板、2in1 等多种设备形态应用需要根据屏幕尺寸自适应布局。柚兔学伴通过WindowUtil实现沉浸式窗口管理通过BreakpointSystem实现多设备断点适配两者协同构建了完整的屏幕适配方案。一、沉浸式窗口实现1.1 全屏布局沉浸式窗口的核心是将内容延伸到系统栏区域。在WindowUtil.requestFullScreen中// common/src/main/ets/util/WindowUtil.etspublicstaticrequestFullScreen(windowStage:window.WindowStage,context:Context):void{windowStage.getMainWindow((err:BusinessError,data:window.Window){if(err.code){Logger.error(TAG,Failed to obtain the main window. Cause:${err.code});return;}constwindowClass:window.Windowdata;try{// HPR 设备特殊处理限制窗口尺寸if(deviceInfo.productSeriesProductSeriesEnum.HPR){WindowUtil.resetWindowSize(windowClass);}// 设置全屏布局——内容延伸到状态栏和导航栏区域constpromise:PromisevoidwindowClass.setWindowLayoutFullScreen(true);promise.then((){Logger.info(TAG,Succeeded in setting the window layout to full-screen mode.);}).catch((err:BusinessError){Logger.error(TAG,Failed to set the window layout to full-screen mode.);});// 获取设备尺寸信息WindowUtil.getDeviceSize(context);}catch{Logger.error(TAG,Failed to set the window layout to full-screen mode.);}});}setWindowLayoutFullScreen(true)使窗口内容布局覆盖整个屏幕包括状态栏和导航指示条区域。但此时系统栏仍然可见只是内容可以延伸到其下方。1.2 隐藏标题栏publicstatichideTitleBar(windowStage:window.WindowStage){windowStage.getMainWindow().then((data:window.Window){try{if(canIUse(SystemCapability.Window.SessionManager)){data.setWindowDecorVisible(false);// 隐藏窗口装饰data.setWindowDecorHeight(CommonConstants.NAVIGATION_HEIGHT);// 设置装饰高度}}catch(error){consterr:BusinessErrorerrorasBusinessError;Logger.error(TAG,Failed to set the visibility of window decor.);}});}setWindowDecorVisible(false)隐藏系统标题栏使应用完全掌控顶部区域。1.3 状态栏颜色控制沉浸式布局下需要根据内容背景调整状态栏图标颜色确保可见性publicstaticupdateStatusBarColor(context:common.BaseContext,isDark:boolean):void{window.getLastWindow(context).then((windowClass:window.Window){try{windowClass.setWindowSystemBarProperties({statusBarContentColor:isDark?StatusBarColorType.WHITE:StatusBarColorType.BLACK}).then((){Logger.info(TAG,Succeeded in setting the system bar properties.);});}catch(error){Logger.error(TAG,Failed to set the system bar properties.);}});}// 状态栏颜色枚举exportenumStatusBarColorType{WHITE#ffffff,// 深色背景使用白色图标BLACK#E5000000,// 浅色背景使用黑色图标90%透明度黑}当页面背景为深色时传入isDark: true状态栏图标变白浅色背景则变黑。二、避让区域管理全屏布局后内容可能与状态栏和底部导航指示条重叠需要获取避让区域高度并预留空间。2.1 获取避让区域publicstaticregisterBreakPoint(windowStage:window.WindowStage){windowStage.getMainWindow((err:BusinessError,data:window.Window){if(err.code){Logger.error(TAG,Failed to get main window:${err.message});return;}try{// 初始化断点系统BreakpointSystem.getInstance().updateWidthBp(data);constglobalInfoModel:GlobalInfoModelAppStorage.get(GlobalInfoModel)||newGlobalInfoModel();// 获取状态栏避让区域constsystemAvoidArea:window.AvoidAreadata.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);globalInfoModel.statusBarHeightpx2vp(systemAvoidArea.topRect.height);// 获取底部导航指示条避让区域constbottomArea:window.AvoidAreadata.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);globalInfoModel.naviIndicatorHeightpx2vp(bottomArea.bottomRect.height);AppStorage.setOrCreate(GlobalInfoModel,globalInfoModel);// 监听窗口尺寸变化data.on(windowSizeChange,()WindowUtil.onWindowSizeChange(data));// 监听避让区域变化data.on(avoidAreaChange,(avoidAreaOption){if(avoidAreaOption.typewindow.AvoidAreaType.TYPE_SYSTEM||avoidAreaOption.typewindow.AvoidAreaType.TYPE_NAVIGATION_INDICATOR){WindowUtil.setAvoidArea(avoidAreaOption.type,avoidAreaOption.area);}});}catch(e){Logger.error(TAG,getWindowAvoidArea failed.);}});}两种避让区域类型TYPE_SYSTEM顶部状态栏区域topRect.height即状态栏高度TYPE_NAVIGATION_INDICATOR底部导航指示条区域bottomRect.height即指示条高度2.2 避让区域动态更新当系统栏状态变化如横竖屏切换、折叠屏展开时通过avoidAreaChange监听器实时更新publicstaticsetAvoidArea(type:window.AvoidAreaType,area:window.AvoidArea){constglobalInfoModel:GlobalInfoModelAppStorage.get(GlobalInfoModel)||newGlobalInfoModel();if(typewindow.AvoidAreaType.TYPE_SYSTEM){globalInfoModel.statusBarHeightpx2vp(area.topRect.height);}else{globalInfoModel.naviIndicatorHeightpx2vp(area.bottomRect.height);}AppStorage.setOrCreate(GlobalInfoModel,globalInfoModel);}2.3 GlobalInfoModel 全局屏幕信息所有屏幕相关信息统一存储在GlobalInfoModel中通过AppStorage全局共享// common/src/main/ets/model/GlobalInfoModel.etsObservedexportclassGlobalInfoModel{publicfoldExpanded:booleanfalse;// 折叠屏是否展开publiccurrentBreakpoint:BreakpointTypeEnumBreakpointTypeEnum.MD;// 当前断点publicnaviIndicatorHeight:number0;// 底部指示条高度vppublicstatusBarHeight:number0;// 状态栏高度vppublicdecorHeight:number0;// 窗口装饰高度publicdeviceHeight:number0;// 设备高度vppublicdeviceWidth:number0;// 设备宽度vp}在 UI 组件中使用StorageLink响应式绑定StorageLink(GlobalInfoModel)globalInfo:GlobalInfoModelnewGlobalInfoModel();// 为内容区域添加顶部 padding避开状态栏.padding({top:this.globalInfo.statusBarHeight})// 为底部添加 padding避开导航指示条.padding({bottom:this.globalInfo.naviIndicatorHeight})三、断点系统3.1 断点定义BreakpointSystem 根据窗口宽度将设备划分为五个断点等级断点宽度范围典型设备XS 320vp小屏穿戴设备SM320vp - 600vp手机竖屏MD600vp - 840vp手机横屏/小平板LG840vp - 1440vp平板/折叠屏XL 1440vp大屏/2in1 设备exportenumBreakpointTypeEnum{XSxs,SMsm,MDmd,LGlg,XLxl,}3.2 BreakpointSystem 单例// common/src/main/ets/util/BreakpointSystem.etsexportclassBreakpointSystem{privatestaticinstance:BreakpointSystem;privatecurrentBreakpoint:BreakpointTypeEnumBreakpointTypeEnum.MD;privateconstructor(){}publicstaticgetInstance():BreakpointSystem{if(!BreakpointSystem.instance){BreakpointSystem.instancenewBreakpointSystem();}returnBreakpointSystem.instance;}publicupdateWidthBp(window:window.Window):void{try{constmainWindow:window.WindowPropertieswindow.getWindowProperties();constwindowWidth:numbermainWindow.windowRect.width;constwindowWidthVppx2vp(windowWidth);// 像素转 VP// HPR 设备直接判定为 XL 断点constdeviceTypedeviceInfo.productSeries;if(deviceTypeProductSeriesEnum.HPR){this.updateCurrentBreakpoint(BreakpointTypeEnum.XL);return;}// 根据窗口宽度 VP 判定断点letwidthBp:BreakpointTypeEnumBreakpointTypeEnum.MD;if(windowWidthVp320){widthBpBreakpointTypeEnum.XS;}elseif(windowWidthVp320windowWidthVp600){widthBpBreakpointTypeEnum.SM;}elseif(windowWidthVp600windowWidthVp840){widthBpBreakpointTypeEnum.MD;}elseif(windowWidthVp840windowWidthVp1440){widthBpBreakpointTypeEnum.LG;}else{widthBpBreakpointTypeEnum.XL;}this.updateCurrentBreakpoint(widthBp);}catch(error){Logger.error(TAG,Failed to getWindowProperties.);}}publicupdateCurrentBreakpoint(breakpoint:BreakpointTypeEnum):void{if(this.currentBreakpoint!breakpoint){this.currentBreakpointbreakpoint;constglobalInfoModel:GlobalInfoModelAppStorage.get(GlobalInfoModel)||newGlobalInfoModel();globalInfoModel.currentBreakpointthis.currentBreakpoint;AppStorage.setOrCreate(GlobalInfoModel,globalInfoModel);}}}关键点使用px2vp()将像素宽度转换为 VP保证不同像素密度的设备断点一致HPR华为 PC 类设备直接判定为 XL 断点断点变化时更新GlobalInfoModel.currentBreakpoint触发 UI 刷新3.3 BreakpointType 泛型类BreakpointTypeT是断点系统的核心工具类可以根据当前断点返回不同的值如布局参数、字体大小、组件实例exportinterfaceBreakpointTypesT{xs?:T;sm:T;md:T;lg:T;xl?:T;}exportclassBreakpointTypeT{privatexs:T;privatesm:T;privatemd:T;privatelg:T;privatexl:T;publicconstructor(param:BreakpointTypesT){this.xsparam.xs??param.sm;// xs 缺省取 sm 值this.smparam.sm;this.mdparam.md;this.lgparam.lg;this.xlparam.xl??param.lg;// xl 缺省取 lg 值}publicgetValue(currentBreakpoint:string):T{if(currentBreakpointBreakpointTypeEnum.XS)returnthis.xs;if(currentBreakpointBreakpointTypeEnum.SM)returnthis.sm;if(currentBreakpointBreakpointTypeEnum.MD)returnthis.md;if(currentBreakpointBreakpointTypeEnum.XL)returnthis.xl;returnthis.lg;}}使用示例——根据断点设置不同的列数和间距constcolumnsnewBreakpointTypenumber({sm:2,// 手机两列md:3,// 横屏三列lg:4,// 平板四列});constgridColcolumns.getValue(this.globalInfo.currentBreakpoint);xs和xl为可选参数缺省时分别回退到sm和lg简化了配置。3.4 窗口尺寸变化监听当窗口尺寸变化旋转屏幕、折叠屏开合、自由窗口拖拽时触发断点重新计算publicstaticonWindowSizeChange(window:window.Window){WindowUtil.getDeviceSize(getContext());// 更新设备尺寸BreakpointSystem.getInstance().onWindowSizeChange(window);// 更新断点}四、HPR 设备特殊处理对于 HPRHarmonyOS PC 类设备柚兔学伴做了特殊适配privatestaticresetWindowSize(windowClass:window.Window):void{if(canIUse(SystemCapability.Window.SessionManager)){constwindowSize:display.Displaydisplay.getDefaultDisplaySync();constappWidth:numberwindowSize.width*9/10;// 90% 屏幕宽度constappHeight:numberwindowSize.height*7/8;// 87.5% 屏幕高度constwindowLimits:window.WindowLimits{maxWidth:appWidth,maxHeight:appHeight,minWidth:appWidth,minHeight:appHeight,};windowClass.setWindowLimits(windowLimits);windowClass.moveWindowToAsync(windowSize.width/20,windowSize.height/16);}}HPR 设备上不使用全屏窗口而是限制为屏幕 90%×87.5% 的固定窗口模拟 PC 应用的窗口体验。五、完整适配流程应用启动 → onWindowStageCreate │ ├── WindowUtil.requestFullScreen() ← 设置全屏布局 │ └── WindowUtil.getDeviceSize() ← 读取设备宽高 │ ├── WindowUtil.registerBreakPoint() ← 注册断点与避让 │ ├── BreakpointSystem.updateWidthBp() ← 计算初始断点 │ ├── getWindowAvoidArea(TYPE_SYSTEM) ← 读取状态栏高度 │ ├── getWindowAvoidArea(TYPE_NAVIGATION_INDICATOR) ← 读取指示条高度 │ ├── on(windowSizeChange) ← 监听窗口变化 │ └── on(avoidAreaChange) ← 监听避让变化 │ └── AppStorage.setOrCreate(GlobalInfoModel) ← 全局共享 │ UI 组件通过 StorageLink 响应式读取 ├── statusBarHeight → 顶部 padding ├── naviIndicatorHeight → 底部 padding ├── currentBreakpoint → BreakpointType.getValue() → 自适应布局 └── deviceWidth / deviceHeight → 条件渲染小结柚兔学伴通过WindowUtil实现沉浸式窗口管理——全屏布局、隐藏标题栏、状态栏颜色适配、避让区域获取与动态更新通过BreakpointSystem实现多设备断点适配——基于窗口宽度 VP 划分五个断点等级提供BreakpointTypeT泛型类简化断点值映射。两者通过GlobalInfoModelAppStorage统一管理屏幕状态UI 组件只需声明式绑定即可实现自适应布局无需手动处理设备差异。
RELATED

相关推荐

GitHub Copilot 工作原理与高效协同编程实践

GitHub Copilot 工作原理与高效协同编程实践

1. 这不是“智能猜词”,而是一场静默的协同编程革命 你有没有过这种体验:光标停在函数名后面,还没敲出括号,VS Code 就已经把整个参数列表、类型注解、甚至三行带 docstring 的函数体,整整齐齐地浮现在你眼前&#xf…

📅 2026/10/12 1:57:01
Trae语义化Docker部署:从FastAPI代码自动生成可审计容器配置

Trae语义化Docker部署:从FastAPI代码自动生成可审计容器配置

1. 项目概述:这不是一次普通部署,而是与 Trae 协同完成的容器化交付闭环“跟 Trae 合作完成项目的docker 部署”——这个标题乍看像一句工作日志,但拆开来看,它其实浓缩了一个正在快速演进的开发协作范式:Trae 不是传统…

📅 2026/10/8 4:58:22
六十四卦编码方案:从二进制到 Unicode,不同的表达不同的代价

六十四卦编码方案:从二进制到 Unicode,不同的表达不同的代价

六十四卦编码方案:从二进制到 Unicode,不同的表达不同的代价 一、同一个卦象,四种编码方式占用的内存差 100 倍 在做一个传统文化数据项目时,遇到了一个最基本但却被忽略的问题:怎么在计算机中表示一个卦&#xff1f…

📅 2026/10/16 12:30:35
MORE NEWS

更多资讯

📰

Spy++ Lite实战:窗口句柄抓取与Windows消息流排查

简介:Spy Lite 3.1.0.1 是一款面向 Windows 开发、测试与逆向分析人员的轻量级窗口句柄探测工具,适合排查窗体结构、控件属性及跨 32/64 位程序的界面问题。压缩包共 4 个文件,约 300KB,包含可执行主程序、COMCTL32.OCX 控件、HTM…

📰

Neo4j企业版5.15.0 Windows安装:JDK17与服务配置排错

简介:Neo4j 企业版 5.15.0 Windows 安装包面向需要突破社区版容量、并发与集群限制的图数据库开发者、运维及架构人员,可用于企业级知识图谱、关系分析和因果集群部署等场景。压缩包共 205 个文件,约 107.64MB,以 178 个 jar 依赖…

📰

微信小程序点餐系统:Spring Boot+原生小程序实战

简介:本资源是一套完整的微信点餐系统毕业设计开源方案,面向计算机专业本科生及Java全栈初学者,解决餐饮行业线上化点餐场景下的前后端协同开发实践问题。资源包含基于SSM框架的Java后端、微信小程序前端及配套文档,覆盖开题报告、…

📰

Kitematic 0.17.11 for Mac:Docker Desktop 的轻量GUI外挂

简介:本资源是面向Mac平台开发者的Docker图形化管理工具Kitematic 0.17.11正式版安装包,专为不熟悉Docker CLI命令、希望快速上手容器部署的初学者及轻量级项目开发者设计。它通过一体化GUI实现镜像搜索、容器启停、端口映射、环境变量配置、卷挂载与日志…

📰

Flask多角色权限系统实战:从选课事务到生产部署避坑指南

简介:这是一套基于Python与Flask框架开发的学生信息管理系统源码,面向高校计算机专业初学者、Web开发入门者及教育信息化实践者,解决多角色协同管理学生基础信息、课程选课与成绩录入等核心教学管理场景。资源包共80个文件,含6个核…

📰

Java Swing+MySQL个人财务系统实战:轻量可控的桌面记账方案

简介:这是一套基于Java Swing开发的个人财务收支管理系统源码,面向Java初学者与C/S架构实践者,聚焦GUI编程、MySQL数据库交互及桌面应用完整开发流程。资源采用EclipseJDKMySQL技术栈,覆盖用户管理、收支分类、收入/支出CRUD、密码…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬