HarmonyOS 鸿蒙Next中Flutter实现区域避让开发指导
HarmonyOS 鸿蒙Next中Flutter实现区域避让开发指导
一、概述
在移动应用开发中,不同设备的屏幕形态各异,如刘海屏、全面屏、折叠屏等,同时系统状态栏、导航栏、软键盘等元素也会占据屏幕空间。为了确保应用内容在各种设备和场景下都能正常显示,不被遮挡,Flutter提供了一系列区域避让的机制和接口。此外,随着折叠屏设备逐渐普及,为了让应用在折叠屏设备上提供良好的用户体验,需要对布局进行特殊处理。FolderStack和FoldSplitContainer这两个组件是折叠屏布局的专用组件。本文将详细介绍Flutter实现区域避让和折叠屏布局组件的原理、适配指导以及具体的场景案例。
使用场景
典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条,其中状态栏和导航条,通常在全屏沉浸式布局下称为避让区,避让区之外的区域称为安全区。界面元素在不同设备上存在差异,下面是不同设备上状态栏、挖孔区、导航栏的位置差异,包括:直板机、PAD、PC、折叠屏(小折叠、双折、三折)。
说明
下图中标记区域含义:1为状态栏、2为挖孔区、3为导航栏。
图1 直板机界面元素示意图
图2 PAD界面元素示意图
图3 PC界面元素示意图
图4 折叠屏–小折叠 界面元素示意图(左图展开态 右图折叠态)
图5 折叠屏–双折叠 界面元素示意图(左图折叠态 右图展开态)
图6 折叠屏–三折叠 界面元素示意图(左图折叠态 右图二屏折叠态 下图三屏全展开态)
面对上述不同设备的避让区差异,可以按照如下三种场景实现应用沉浸式效果:
1.1 安全区布局场景
布局系统保持安全区内布局,确保应用内容不会延伸到状态栏、导航栏区域。
1.2 安全区布局+背景沉浸模式
布局系统保持安全区内布局,然后延伸绘制内容(如背景色、背景图)到状态栏和导航条区域,实现沉浸式效果。
1.3 全屏布局+避让场景
布局系统保持全屏布局,通过相关接口获取避让区域位置、大小等信息,调整元素位置,确保不会被避让区遮挡。
二、实现原理
2.1 区域避让实现原理
区域避让主要借助 AvoidArea API 对外提供能力的接口来实现,该接口包含几个核心方法,用于处理与区域避让相关的操作。
• getWindowAvoidArea
:此方法接收一个 AvoidAreaType
类型的参数,通过该参数可以获取当前应用窗口内容需要规避的区域。这些区域可能包括系统栏、刘海屏、手势操作区、软键盘等与窗口内容重叠时需要避让的区域。例如,在处理刘海屏设备时,应用可以通过该方法获取刘海屏区域的信息,从而调整内容布局,避免内容被刘海遮挡。
• addAvoidAreaListener
:该方法用于添加系统规避区变化事件的监听。当系统规避区发生变化时,如软键盘弹出或收起、设备旋转等,会触发相应的回调函数,应用可以在回调中更新布局。
• removeAvoidAreaListener
:用于移除之前添加的系统规避区变化事件监听,避免不必要的回调触发,节省系统资源。
2.2 折叠屏布局组件实现原理
FoldSplitContainer
folder_split_view.dart
定义了 FoldSplitContainer 组件,用于实现折叠屏二分栏、三分栏在展开态、悬停态以及折叠态的区域控制。
- 状态监听:通过
FolderStackPlugin.folderStateEvents
监听折叠屏状态变化,当状态变化时更新界面。 - 布局构建:根据不同的折叠屏状态(展开、半折叠、折叠)调用不同的布局构建方法,如
_buildExpandedLayout
、_buildHoverModeLayout
和_buildFoldedRegionLayout
。 - 比例转换:通过
_ratioToFlex
方法将比例转换为整数flex
因子,用于Flex
组件的布局。
FolderStack
folder_stack.dart
定义了 FolderStack 组件,继承于 Stack 控件,新增了折叠屏悬停能力,通过识别 upperItems 自动避让折叠屏折痕区后移到上半屏。
- 状态监听:同样通过
FolderStackPlugin.folderStateEvents
监听折叠屏状态变化。 - 布局处理:当设备处于半折叠且折痕方向为水平时,将
upperItems
中的子组件堆叠到上半屏,其他组件堆叠在下半屏。 - 上下屏:通过折痕区域范围算出上下屏占用比例,然后使用
Flex
组件的布局。
三、适配指导
3.1 区域避让适配指导
安全区布局场景
安全区布局场景主要是为了确保应用内容不会被系统状态栏、导航栏等遮挡。Flutter 提供了 SafeArea 组件,该组件可以自动将内容放置在安全区域内。同时,也可以结合 AvoidArea API 获取的避让区域信息进行更精确的布局。
安全区布局 + 背景沉浸模式
在背景沉浸模式下,需要使用 Stack 组件,背景全屏展示,然后使用 Safearea 包裹安全区域。
全屏布局 + 避让场景
在全屏布局中,需要隐藏系统状态栏和导航栏,并添加避让区域变化监听。根据避让区域的变化动态调整布局,确保应用在各种情况下都能正常显示。
-
隐藏状态栏和导航栏。
-
添加避让区域变化监听,根据避让区域的变化动态调整布局。
3.2 折叠屏布局组件适配指导
在使用 FoldSplitContainer 和 FolderStack 组件时,需要根据不同的折叠状态(展开、半折叠、折叠)进行布局适配。需注意这两个组件必须占用整个屏幕,否则位置会计算失败。
-
导入区域避让功能库。
-
FoldSplitContainer 可以通过配置不同的布局选项,如 FoldedRegionLayoutOptions、ExpandedRegionLayoutOptions 和 HoverModeRegionLayoutOptions,来实现不同状态下的布局效果。
-
FolderStack 在悬停状态通过识别 upperItems 自动避让折叠屏折痕区后移到上半屏,上方为显示区下方为操作区。
四、场景案例
4.1 区域避让场景案例
在 avoid_area_sample 示例库中,展示了区域避让的具体使用方法。以下是 AvoidAreaManager 类中的部分代码。
-
根据固定区域计算出上下左右需要避让的距离,然后用 padding 封装。
-
计算异形避让区域(刘海屏)的方位以及距离。
-
添加区域避让监听,避让区域发生变化后重新计算布局。
-
使用 avoidAreaState.padding 做整体避让,然后根据 avoidAreaState.cutoutPosition 判断挖孔区域避让。
4.2 折叠屏布局组件场景案例
FoldSplitContainer 使用示例
fold_split_container_ui.dart
文件展示了 FoldSplitContainer 组件的使用方法。通过配置不同的布局选项,可以实现折叠态、悬停态和展开态的布局控制。
FolderStack 使用示例
folder_stack_ui.dart
文件展示了 FolderStack 组件的使用方法。通过配置 upperItems 属性,可以指定悬停态时需要移到上半屏的子组件。
五、示例代码
组件库的地址为:hadss_avoid_area,开发者可以通过该地址查看完整的组件接入指导,并根据自己的需求进行开发。
示例库的地址为:avoid_area_sample,开发者可以通过该地址查看完整的区域避让示例代码,并根据自己的需求进行修改和扩展。
更多关于HarmonyOS 鸿蒙Next中Flutter实现区域避让开发指导的实战教程也可以访问 https://www.itying.com/category-92-b0.html
在HarmonyOS Next中使用Flutter实现区域避让,可通过Flutter的AvoidInset
组件或自定义布局逻辑处理。使用SafeArea
组件可自动避开系统UI区域(如状态栏)。对于特定区域避让,需结合MediaQuery
获取屏幕信息,通过Padding
或ConstrainedBox
约束内容区域。Flutter的布局系统(如Stack
+Positioned
)可用于动态避让悬浮元素。鸿蒙的ohos.agp
图形库与Flutter无直接交互,需完全依赖Flutter原生能力实现。注意鸿蒙Next的屏幕适配差异,建议测试不同设备。
更多关于HarmonyOS 鸿蒙Next中Flutter实现区域避让开发指导的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在HarmonyOS Next中使用Flutter实现区域避让开发,主要涉及AvoidArea API和折叠屏布局组件(FolderStack/FoldSplitContainer)的使用。核心要点如下:
- 区域避让实现:
- 通过getWindowAvoidArea获取避让区域信息
- 使用addAvoidAreaListener监听区域变化
- 三种适配场景:安全区布局、背景沉浸模式、全屏布局+避让
- 折叠屏适配:
- FolderStack:自动识别折痕区域,将upperItems内容移至上半屏
- FoldSplitContainer:支持二分栏/三分栏布局,适配展开/折叠/悬停状态
- 通过FoldingFeature获取折叠状态(展开/半折叠/折叠)和折痕方向
- 关键API:
- AvoidAreaPlugin.ets提供原生能力
- FolderStateStreamHandler处理折叠状态变化
- 通过EventChannel实现Flutter与原生通信
建议参考提供的示例代码,特别是avoid_area_sample和folder_stack_ui.dart等文件,了解具体实现细节。注意组件需要全屏使用以确保正确计算布局位置。