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

HarmonyOS FoldStatus 与 FoldDisplayMode 枚举深度解析:折叠屏开发不再难

文章目录

    • 一、前言
    • 二、工具函数方法一览
    • 三、状态查询方法详解
      • 3.1 `isFoldable()` — 检测是否可折叠设备
      • 3.2 `getFoldStatus()` — 获取折叠状态
      • 3.3 `getFoldDisplayMode()` — 获取折叠显示模式
    • 四、监听方法详解
      • 4.1 折叠状态变化监听
      • 4.2 折叠角度变化监听
    • 五、完整演示代码
      • 5.1 状态查询
      • 5.2 监听器注册与注销
      • 5.3 UI 渲染
    • 六、生命周期中正确管理监听器
    • 七、实际应用场景
      • 场景 1:折叠屏布局自适应
      • 场景 2:根据角度触发特效
    • 八、小结

一、前言

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓

HarmonyOS 生态中有华为 Mate X 系列等折叠屏设备。折叠屏设备有多种独特的显示状态:完全展开、完全折叠、半折叠(悬停态);还有多种显示模式:全屏、主屏、子屏、双屏协同……

DisplayUtil提供了检测折叠状态的方法,以及监听折叠状态/角度变化的事件接口。本文详细讲解这些能力,并结合DisplayUtilDemoPage.ets中的完整演示代码进行说明。


二、工具函数方法一览

// 检查设备是否可折叠staticisFoldable():boolean// 获取当前折叠状态(展开/折叠/半折叠)staticgetFoldStatus():display.FoldStatus// 获取当前折叠显示模式(全屏/主屏/子屏/协同)staticgetFoldDisplayMode():display.FoldDisplayMode// 监听折叠状态变化staticonFoldStatusChange(callback:Callback<display.FoldStatus>):void// 取消监听折叠状态变化staticoffFoldStatusChange(callback?:Callback<display.FoldStatus>):void// 监听折叠角度变化(0~180°)staticonFoldAngleChange(callback:Callback<Array<number>>):void// 取消监听折叠角度变化staticoffFoldAngleChange(callback?:Callback<Array<number>>):void

三、状态查询方法详解

3.1isFoldable()— 检测是否可折叠设备

源码:

staticisFoldable():boolean{returndisplay.isFoldable();}

说明:
返回true表示是折叠屏设备,false表示普通屏幕。这是一切折叠屏适配的前提判断——在非折叠设备上调用折叠相关 API 没有意义。

注意:需要SystemCapability.Window.SessionManager,若系统不支持会抛出BusinessError 1400003


3.2getFoldStatus()— 获取折叠状态

源码:

staticgetFoldStatus():display.FoldStatus{returndisplay.getFoldStatus();}

display.FoldStatus枚举值说明:

枚举值数字含义
FOLD_STATUS_UNKNOWN0折叠状态未知
FOLD_STATUS_EXPANDED1完全展开
FOLD_STATUS_FOLDED2完全折叠
FOLD_STATUS_HALF_FOLDED3半折叠(悬停态,适合桌面模式)

Demo 中的枚举转换:

getFoldStatusLabel(status:display.FoldStatus):string{switch(status){casedisplay.FoldStatus.FOLD_STATUS_UNKNOWN:return'未知 (FOLD_STATUS_UNKNOWN=0)';casedisplay.FoldStatus.FOLD_STATUS_EXPANDED:return'完全展开 (FOLD_STATUS_EXPANDED=1)';casedisplay.FoldStatus.FOLD_STATUS_FOLDED:return'折叠 (FOLD_STATUS_FOLDED=2)';casedisplay.FoldStatus.FOLD_STATUS_HALF_FOLDED:return'半折叠 (FOLD_STATUS_HALF_FOLDED=3)';default:return`未知 (${status})`;}}

3.3getFoldDisplayMode()— 获取折叠显示模式

源码:

staticgetFoldDisplayMode():display.FoldDisplayMode{returndisplay.getFoldDisplayMode();}

display.FoldDisplayMode枚举值说明:

枚举值数字含义
FOLD_DISPLAY_MODE_UNKNOWN0显示模式未知
FOLD_DISPLAY_MODE_FULL1全屏(展开后使用整个大屏)
FOLD_DISPLAY_MODE_MAIN2主屏幕显示(内屏)
FOLD_DISPLAY_MODE_SUB3子屏幕显示(外屏)
FOLD_DISPLAY_MODE_COORDINATION4双屏协同(内外屏同时工作)

Demo 中的枚举转换:

getFoldDisplayModeLabel(mode:display.FoldDisplayMode):string{switch(mode){casedisplay.FoldDisplayMode.FOLD_DISPLAY_MODE_UNKNOWN:return'未知 (FOLD_DISPLAY_MODE_UNKNOWN=0)';casedisplay.FoldDisplayMode.FOLD_DISPLAY_MODE_FULL:return'全屏 (FOLD_DISPLAY_MODE_FULL=1)';casedisplay.FoldDisplayMode.FOLD_DISPLAY_MODE_MAIN:return'主屏 (FOLD_DISPLAY_MODE_MAIN=2)';casedisplay.FoldDisplayMode.FOLD_DISPLAY_MODE_SUB:return'子屏 (FOLD_DISPLAY_MODE_SUB=3)';casedisplay.FoldDisplayMode.FOLD_DISPLAY_MODE_COORDINATION:return'双屏协同 (FOLD_DISPLAY_MODE_COORDINATION=4)';default:return`未知 (${mode})`;}}

四、监听方法详解

4.1 折叠状态变化监听

源码:

staticonFoldStatusChange(callback:Callback<display.FoldStatus>){display.on('foldStatusChange',callback);}staticoffFoldStatusChange(callback?:Callback<display.FoldStatus>){display.off('foldStatusChange',callback);}

说明:

  • onFoldStatusChange:注册监听,当折叠状态改变时(如从展开折叠、折叠展开),回调函数会被触发。
  • offFoldStatusChange:注销监听。callback参数可选,若不传则注销所有折叠状态监听器。

4.2 折叠角度变化监听

源码:

staticonFoldAngleChange(callback:Callback<Array<number>>){display.on('foldAngleChange',callback);}staticoffFoldAngleChange(callback?:Callback<Array<number>>){display.off('foldAngleChange',callback);}

说明:

  • 回调函数接收一个Array<number>,每个元素是对应折轴的角度(0~180 度)。
  • 单折轴设备返回长度为 1 的数组;双折轴设备(如三折屏)返回长度为 2 的数组,第一个值是折轴一的角度,第二个是折轴二的角度。
  • 折叠角度在用户手动调整屏幕折叠程度时会持续变化。

五、完整演示代码

5.1 状态查询

loadFoldInfo(){// isFoldable()constfoldable=DisplayUtil.isFoldable();this.isFoldableResult=foldable?'可折叠设备':'非折叠设备';this.addLog('Fold',`isFoldable() =${foldable}`,'info');// getFoldStatus()constfoldStatus=DisplayUtil.getFoldStatus();this.foldStatusValue=foldStatus.toString();this.foldStatusLabel=this.getFoldStatusLabel(foldStatus);this.addLog('Fold',`getFoldStatus() =${this.foldStatusLabel}`,'info');// getFoldDisplayMode()constfoldMode=DisplayUtil.getFoldDisplayMode();this.foldDisplayModeValue=foldMode.toString();this.foldDisplayModeLabel=this.getFoldDisplayModeLabel(foldMode);this.addLog('Fold',`getFoldDisplayMode() =${this.foldDisplayModeLabel}`,'info');}

5.2 监听器注册与注销

registerFoldStatusChange(){if(this.foldStatusCallback!==undefined){this.addLog('Fold','折叠状态监听已注册,无需重复','warn');return;}this.foldStatusCallback=(status:display.FoldStatus)=>{constlabel=this.getFoldStatusLabel(status);this.lastFoldStatusChange=label;this.addLog('Fold',`折叠状态变化:${label}`,'success');};DisplayUtil.onFoldStatusChange(this.foldStatusCallback);this.foldStatusChangeStatus='已注册';this.foldStatusChangeColor='#00C853';this.addLog('Fold','onFoldStatusChange() 已注册','success');}unregisterFoldStatusChange(){if(this.foldStatusCallback!==undefined){DisplayUtil.offFoldStatusChange(this.foldStatusCallback);this.foldStatusCallback=undefined;this.foldStatusChangeStatus='已注销';this.foldStatusChangeColor='#888';this.addLog('Fold','offFoldStatusChange() 已注销','warn');}}registerFoldAngleChange(){if(this.foldAngleCallback!==undefined){this.addLog('Fold','折叠角度监听已注册,无需重复','warn');return;}this.foldAngleCallback=(angles:Array<number>)=>{this.lastFoldAngleChange=angles.length>0?angles.map(a=>`${a}°`).join(', '):'无数据';this.addLog('Fold',`折叠角度变化:${this.lastFoldAngleChange}`,'success');};DisplayUtil.onFoldAngleChange(this.foldAngleCallback);this.foldAngleChangeStatus='已注册';this.foldAngleChangeColor='#00C853';this.addLog('Fold','onFoldAngleChange() 已注册','success');}

5.3 UI 渲染

// ══ 折叠设备 ═══════════════════════════════════════if(this.activeTab===3){// 折叠状态概览Column(){Text('折叠设备状态').fontSize(13).fontColor('#666').fontWeight(FontWeight.Medium).alignSelf(ItemAlign.Start).margin({bottom:10})Row(){Column(){Text(this.isFoldableResult).fontSize(14).fontWeight(FontWeight.Bold).fontColor(this.isFoldableResult.includes('可折叠')?'#00C853':'#888')Text('isFoldable()').fontSize(10).fontColor('#888')}.layoutWeight(1).alignItems(HorizontalAlign.Center)Column(){Text(this.foldStatusLabel.includes('未知')?'N/A':this.foldStatusLabel.split(' ')[0]).fontSize(14).fontWeight(FontWeight.Bold).fontColor('#4080FF')Text('getFoldStatus()').fontSize(10).fontColor('#888')}.layoutWeight(1).alignItems(HorizontalAlign.Center)Column(){Text(this.foldDisplayModeLabel.includes('未知')?'N/A':this.foldDisplayModeLabel.split(' ')[0]).fontSize(14).fontWeight(FontWeight.Bold).fontColor('#D63384')Text('getFoldDisplayMode()').fontSize(10).fontColor('#888')}.layoutWeight(1).alignItems(HorizontalAlign.Center)}.width('100%').margin({bottom:10})Button('刷新折叠状态').fontSize(12).height(34).backgroundColor('#4080FF').fontColor('#FFF').onClick(()=>{this.loadFoldInfo();})}.width('100%').padding(14).backgroundColor('#FFFFFF').borderRadius(12)// 枚举值说明this.buildSectionCard('FoldStatus 枚举值',[{label:'FOLD_STATUS_UNKNOWN = 0',value:'未知'},{label:'FOLD_STATUS_EXPANDED = 1',value:'完全展开'},{label:'FOLD_STATUS_FOLDED = 2',value:'折叠'},{label:'FOLD_STATUS_HALF_FOLDED = 3',value:'半折叠(悬停态)'},]asSectionRow[])this.buildSectionCard('FoldDisplayMode 枚举值',[{label:'FOLD_DISPLAY_MODE_UNKNOWN = 0',value:'未知'},{label:'FOLD_DISPLAY_MODE_FULL = 1',value:'全屏显示'},{label:'FOLD_DISPLAY_MODE_MAIN = 2',value:'主屏幕显示'},{label:'FOLD_DISPLAY_MODE_SUB = 3',value:'子屏幕显示'},{label:'FOLD_DISPLAY_MODE_COORDINATION = 4',value:'双屏协同'},]asSectionRow[])}

六、生命周期中正确管理监听器

一个非常重要的实践是:在页面销毁时注销所有监听器,避免内存泄漏。

aboutToDisappear():void{this.unregisterAllListeners();}unregisterAllListeners(){if(this.foldStatusCallback!==undefined){DisplayUtil.offFoldStatusChange(this.foldStatusCallback);this.foldStatusCallback=undefined;}if(this.foldAngleCallback!==undefined){DisplayUtil.offFoldAngleChange(this.foldAngleCallback);this.foldAngleCallback=undefined;}}

七、实际应用场景

场景 1:折叠屏布局自适应

DisplayUtil.onFoldStatusChange((status)=>{if(status===display.FoldStatus.FOLD_STATUS_EXPANDED){// 展开状态:使用大屏布局(双列)this.useWideLayout=true;}elseif(status===display.FoldStatus.FOLD_STATUS_FOLDED){// 折叠状态:使用小屏布局(单列)this.useWideLayout=false;}elseif(status===display.FoldStatus.FOLD_STATUS_HALF_FOLDED){// 半折叠悬停态:可以做"帐篷模式"布局this.useTentLayout=true;}});

场景 2:根据角度触发特效

DisplayUtil.onFoldAngleChange((angles)=>{constangle=angles[0];if(angle>90){// 屏幕几乎展开,进入全屏模式this.enterFullScreenMode();}elseif(angle<30){// 屏幕几乎合拢this.enterCompactMode();}});

八、小结

方法说明
isFoldable()判断是否折叠设备(先决条件)
getFoldStatus()获取当前折叠状态(未知/展开/折叠/半折叠)
getFoldDisplayMode()获取显示模式(全屏/主屏/子屏/协同)
onFoldStatusChange(cb)监听折叠状态变化
offFoldStatusChange(cb?)注销折叠状态监听
onFoldAngleChange(cb)监听折叠角度(0~180°)
offFoldAngleChange(cb?)注销折叠角度监听

折叠屏是 HarmonyOS 生态的重要差异化能力,掌握这些 API,能让你的应用在折叠屏设备上展现出与众不同的体验。

http://www.gsyq.cn/news/1410143.html

相关文章:

  • Java 内存区域(6 大存储位置)超清晰总结
  • 从零构建AI代码助手:RAG架构、智能分块与向量检索实战
  • 2026年口碑好的山东防坠落安全绳/高空作业安全绳厂家推荐与选型指南 - 品牌宣传支持者
  • AI设计工具:让AI帮你设计UI界面
  • 账单不是因为模型贵,而是因为请求长歪了:我怎么排查 token 成本
  • 网络数据传输的过程:一条微信消息的奇妙旅行
  • ESP32-S3 WiFi性能到底如何?我实测了TCP/UDP,结果和官方数据有点不一样
  • Keil MDK 5中解决RL-ARM库路径错误的实践指南
  • E5-small常见问题解答:解决使用过程中的10个典型问题
  • C166中断管道问题解析与解决方案
  • FlashAttention与时间序列预测:让AI预知未来
  • 2026年4月国内诚信的窗帘门店口碑推荐,墙布/智能窗帘/遮阳卷帘/天窗/家装软硬包/商场卷帘/木卷帘,窗帘品牌哪家专业 - 品牌推荐师
  • 2026年 哈尔滨无人机执照培训学校推荐榜:CAAC多旋翼教学,视距内/超视距驾驶员与教员考证,报名及无人机驾驶证专业指导 - 品牌企业推荐师(官方)
  • 面试官问‘加法器有几种?’:从行波进位到前缀加法器的性能演进与面试考点解析
  • 还在靠人肉发版?真正的 DevOps 平台,凌晨3点都能自己干活
  • 微信聊天记录永久保存终极方案:3步搞定WeChatMsg免费备份与智能分析
  • R语言偏相关分析实战:用ppcor包和自定义函数搞定土壤微生物数据
  • 基于Android11 的wifi自动连接流程梳理
  • FlashAttention与信息检索:让AI秒找答案
  • 别再傻傻分不清了!Power BI里COUNT、COUNTA、COUNTBLANK到底啥区别?一个例子讲透
  • 2026世界杯洛杉矶SoFi体育场:50亿造价的天价足球圣殿
  • 从MLM到RTD:一文读懂DeBERTa V3的预训练任务革新与HuggingFace快速上手
  • 202614读书笔记|《中亚:女孩的归宿是证明“清白”,男孩的征途是星辰大海》——“自由”不是所有人都能轻易拥有
  • 手把手教你配置Redis,搞定等保2.0测评里的那些‘坑’(附配置文件详解)
  • 【多无人机集群控制11】鲁棒编队跟踪仿真,滑模与PID对比,MATLAB例程
  • 第6篇_Retain_Will_KeepAlive_工业现场为什么不能只会转发PUBLISH
  • 第4篇_SUBSCRIBE不是存个字符串_Broker怎么维护订阅表通配符和多客户端路由
  • 如何零费用享受全套现代化 IT 基础设施的终极流程
  • Win11Debloat:3分钟完成Windows 11终极优化与深度清理的免费神器
  • 新手教程:5分钟实现一个智能体