当前位置: 首页 > 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.jsqmd.com/news/900901/

相关文章:

  • 多家对比才知道!机闸一体式钢制闸门哪家好、哪家优惠?认准河北闸之都实体厂家,可定制,品质价格双保障 - 栗子测评
  • 10个免费VMware Workstation Pro 17许可证密钥:专业虚拟化快速激活指南
  • LightRAG 入门指南:手把手教你用图增强 RAG 系统
  • 别再死记硬背了!用COMSOL做场路耦合,搞懂‘外部U vs. I’和‘外部I vs. U’到底怎么选
  • 2026年移动岗亭十大品牌厂家推荐:不锈钢/铝合金/雕花板岗亭,小区/工地/景区/警务/收费多场景定制选购指南 - 品牌企业推荐师(官方)
  • 从理论到实践:MiniCPM5-1B-MLX架构设计与实现原理深度剖析
  • 智能体时代,AI支付会是下一个“二维码”吗?
  • Bat批处理进阶玩法:用ren命令批量重命名,实现‘去头掐尾’和‘中间替换’
  • 2026年 EPS/EPP源头厂家最新推荐榜:东莞EPS颗粒、阻燃EPS板材、EPP保温箱及EPP托盘与周转箱专业实力深度解析 - 品牌企业推荐师(官方)
  • R语言偏相关分析实战:用ppcor包和自定义函数搞定土壤微生物数据
  • SY_AICC/gpt2安全与伦理:如何规避生成文本中的偏见与风险
  • 避坑指南:TextMeshPro打字机效果实现时,为什么你的字符淡入会‘穿帮’?
  • AURIX TC397内存不够用?三种方法教你手动指定变量到PSRR、DSRR等地址空间
  • 2026年口碑好的山东防坠落安全绳/高空作业安全绳厂家推荐与选型指南 - 品牌宣传支持者
  • 终极FPDF指南:5分钟学会用纯PHP生成专业PDF文档
  • 数字隔离器的用途和技术指标有哪些
  • 江西不锈钢水表箱怎么选?认准源头工厂!江西泗方水处理是专业批发厂家,可定制加工,靠谱厂家推荐看这里 - 栗子测评
  • 基于Python的数据画像解析工具:从平台数据到个人数字画像
  • 面试高频:Spring AI 统一聊天入口怎么设计,这次把路由和降级讲具体
  • PowerDesigner画UML图总是不好看?这5个隐藏的样式配置技巧(含箭头文字显示修复)
  • 2026年 饰品回收推荐榜单:东莞卡地亚/梵克雅宝/宝格丽/蒂芙尼/香奈儿等大牌饰品高价上门回收与专业收购指南 - 品牌企业推荐师(官方)
  • 临沂批发必看!旭阳电器商行精选扬子骆驼、熊猫、米小可电风扇,冷风机、商务扇优质货源,本地靠谱供货商一站式推荐 - 栗子测评
  • 首次使用 Taotoken 从注册到发出第一个 API 请求的全记录
  • 账单不是因为模型贵,而是因为请求长歪了:我怎么排查 token 成本
  • Linux基础开发工具集合
  • 工程采购发愁?找不到合适机闸一体式钢制、铸铁闸门厂家?河北闸之都实体工厂,可定做,物美价廉质量过硬 - 栗子测评
  • nli-roberta-base开发者进阶:如何基于该模型构建复杂的多模态推理系统
  • 探索AI视觉革命:如何让计算机真正“看懂“人体姿态
  • 避坑指南:STM32WLE5CCU6移植LoRaWAN_AT_Slave工程时,那些CubeMX和BSP包的常见问题
  • tmux不止是后台挂起:5个提升终端效率的进阶玩法(分屏、会话管理、窗口同步)