☰
Flutter三方库适配OpenHarmony【harmony_ui】容器类控件实战:列表、卡片、弹出框、气泡与光感半模态
2026/10/28 10:12:06 网站建设 项目流程

前言

harmony_ui是 Material/Cupertino 风格的 Flutter 组件库,完整实现了HarmonyOS 设计语言,覆盖官方「控件概览」6 大类 42 个控件,并额外实现了沉浸光感材质与 UI Design Kit 增强能力。本系列按官方控件类别逐类实战:前五篇分别是导航类、展示类、操作类、输入类、选择类,本篇是第 6 篇:容器类。

容器类是"装内容的壳":列表/列表项(OhosList/OhosListTile)承载信息流与设置页,卡片(OhosCard)是信息流的单元,弹出框(showOhosDialog)、气泡(showOhosPopup)、半模态(showOhosBottomSheet)是内容之外的"第二层空间"。其中半模态面板默认使用ULTRA_THICK 沉浸光感材质,是容器类与第 7 篇增强类的交汇点。

所有示例代码都在OpenHarmony 模拟器上直接运行验证(Flutter3.47.7-ohos-1.0.1+ DevEco Studio26.0.0 Release,截图环境:API 26,1280×2832)。环境搭建、依赖引入与构建步骤见文首「环境与版本」「安装与引入 harmony_ui」以及第九节;仓库地址:AtomGit / GitHub。

环境与版本

本文的示例与截图基于以下环境组合(2026-10 实测):

组件版本说明
Flutter SDK(OH 适配版)3.47.7-ohos-1.0.1oh-flutter/flutter_flutter,oh-3.47-dev分支
DevEco Studio26.0.0 Release提供 hvigor / ohpm / hdc / JBR 等工具链
OpenHarmony SDK / APIAPI 26(26.0.0)模拟器与 SDK 均为 API 26
运行设备OpenHarmony 模拟器API 26,1280×2832

环境搭建(分叉获取、DevEco Studio 与 SDK 配置、模拟器创建)请按官方指导操作:OpenHarmony-flutter 环境搭建指导。

harmony_ui是纯 Dart/Flutter 组件库,不依赖 ohos 平台通道;在官方 Flutter SDK 上也能运行(用于跨平台预览)。只有跑example/ohos工程、构建 HAP 时才需要上面的 OH 适配版 SDK。

安装与引入 harmony_ui

harmony_ui已发布到 pub.dev,当前最新版本是0.3.0。在应用工程的pubspec.yaml中声明:

dependencies:flutter:sdk:flutterharmony_ui:^0.3.0

然后拉取依赖:

fvm flutter pub get

如果团队需要固定到仓库的某个提交(例如使用尚未发版的修复),改用 git 依赖:

dependencies:harmony_ui:git:url:https://atomgit.com/oh-flutter/harmony_ui.gitref:v0.3.0# 固定 tag;写 main 则跟随最新提交
fvm flutter pub get

pub.dev 与 git 两种方式二选一,不要同时声明。CI 中建议固定 tag(如v0.3.0)而不是main,避免构建结果随上游漂移。harmony_ui目前只依赖qr一个三方包,ohos_icons是可选配套图标包,不引入也不影响组件使用。

一、容器类总览

官方控件实现一句话说明
列表 / 列表项OhosList/OhosListTile分组列表,选中态/危险项
卡片OhosCard24vp 大圆角,按压反馈
弹出框OhosAlertDialog/showOhosDialog双按钮确认,危险操作红色
气泡提示showOhosPopup锚定控件的功能引导
半模态面板showOhosBottomSheetULTRA_THICK 光感材质
(布局容器)栅格/响应式OhosGrid/OhosResponsiveBuilder4/8/12 列断点布局
(增强)横滑列表项OhosListItem左滑操作,整划删除

容器类整体效果(gallery「容器」分类页,模拟器实机):

容器类:OhosList分组列表、OhosCard卡片、showOhosDialog弹出框、showOhosBottomSheet光感半模态面板

二、列表 OhosList 与列表项

2.1 分组列表

OhosList是"分组标题 + 列表项 + 分隔线"的组合容器,设置页标准形态。header传OhosSubheader(支持尾部"更多"):

OhosList(header:constOhosSubheader(title:'通用'),children:[OhosListTile(leading:constIcon(Icons.wifi),title:constText('无线网络'),subtitle:constText('已连接'),trailing:constIcon(Icons.chevron_right),onTap:_openWifi,),constOhosDivider(),OhosListTile(leading:constIcon(Icons.bluetooth),title:constText('蓝牙'),trailing:constIcon(Icons.chevron_right),onTap:_openBluetooth,),],)

OhosListTile四区结构(leading / title / subtitle / trailing)与ListTile一致,行高、内边距、分隔线全部按官方规范内置。

2.2 选中态与危险项

列表项内置两个官方状态:selected(品牌色高亮,表示"当前项")与danger(危险操作红色文字):

OhosList(header:constOhosSubheader(title:'通知'),children:[OhosListTile(leading:constIcon(Icons.push_pin_outlined),title:constText('消息推送'),selected:true,// 选中态:品牌色高亮trailing:OhosSwitch(value:_push,onChanged:_onPush),),constOhosDivider(),OhosListTile(leading:constIcon(Icons.delete_outline),title:constText('清空聊天记录'),danger:true,// 危险项:红色onTap:_clearChat,),],)
  • 长列表场景用ListView.builder+OhosListTile手工拼装(OhosList适合短列表直铺);
  • 列表项按压反馈(10% 黑叠加)内置,无需InkWell包裹。

三、卡片 OhosCard

3.1 基础卡片

OhosCard对齐官方卡片规范:24vp 大圆角、分层背景(comp_background_primary白底)、按压反馈,默认内边距 16vp:

OhosCard(onTap:_openDetail,child:constColumn(crossAxisAlignment:CrossAxisAlignment.start,children:[OhosText('卡片标题',level:OhosTextLevel.titleLarge),SizedBox(height:8),OhosText('卡片摘要文字,最多两行,超出省略。',level:OhosTextLevel.bodyMedium),],),)
  • elevation默认 0(鸿蒙卡片靠背景分层而非投影),特殊场景可加;
  • margin/color可覆盖默认值(灰底卡片用theme.compBackgroundGrayColor)。

3.2 图片卡片

信息流单元的标准结构(头图 + 标题 + 摘要 + 尾部信息):

OhosCard(onTap:_openDetail,margin:constEdgeInsets.symmetric(horizontal:16,vertical:8),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:const[OhosImage(image:NetworkImage('https://example.com/cover.png'),height:160,borderRadius:20,),SizedBox(height:12),Padding(padding:EdgeInsets.symmetric(horizontal:4),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[OhosText('文章标题',level:OhosTextLevel.titleMedium),SizedBox(height:4),OhosText('摘要文字摘要文字摘要文字摘要文字摘要文字。',level:OhosTextLevel.bodySmall),SizedBox(height:12),Row(children:[Icon(Icons.person_outline,size:16,color:Colors.black38),SizedBox(width:4),Text('作者名',style:TextStyle(fontSize:12,color:Colors.black38)),],),],),),],),)

卡片圆角层次:卡片 24vp > 卡片内图片 20~16vp > 图片内元素 8vp——圆角逐级递减是鸿蒙"嵌套容器"的视觉惯例,OhosImage默认 8vp 正好对应最内层。

四、弹出框 showOhosDialog

showOhosDialog返回Future,OhosDialogAction支持danger危险色,对齐官方弹出框规范:

finalbool?ok=awaitshowOhosDialog<bool>(context:context,title:'删除文件?',content:'删除后无法恢复,请确认是否继续。',actions:[OhosDialogAction(label:'取消',onPressed:()=>Navigator.pop(context,false),),OhosDialogAction(label:'删除',danger:true,onPressed:()=>Navigator.pop(context,true),),],);
场景标题按钮组合备注
破坏性确认具体后果取消 + 危险操作删除/清空/退订
普通确认动作名取消 + 确定提交/退出登录
信息告知结果单按钮"知道了"操作完成提示
选择问题多选项2-3 个互斥选项
  • 对话框内容保持"标题 + 两行内说明",长内容改用半模态;
  • 返回值为最后一个Navigator.pop的值,未操作(点遮罩)按默认策略处理。

弹出框实机效果:

showOhosDialog弹出框:标题、内容、取消/危险删除双操作

五、气泡提示 showOhosPopup

showOhosPopup通过GlobalKey锚定目标控件,显示圆角气泡 + 指向箭头,用于新手引导与功能说明(展示类篇有基本用法,这里讲组合模式):

finalguideKey=GlobalKey();// 分步引导:第 1 步指向搜索框showOhosPopup(context:context,content:'在这里搜索全部内容',targetKey:guideKey,);
  • 多个引导步骤时业务侧维护步骤索引,每步换一个targetKey;
  • 气泡与OhosBadge红点配合:"红点吸引注意 + 气泡说明功能"是标准引导组合;
  • 引导状态(是否已展示过)用本地存储记录,避免每次启动重复弹。

六、半模态面板 showOhosBottomSheet

6.1 基本半模态

showOhosBottomSheet从底部滑出半模态面板,默认 ULTRA_THICK 光感材质(40vp sigma),适合分享面板、筛选面板、信息预览:

awaitshowOhosBottomSheet(context:context,title:'分享到',content:SizedBox(height:200,child:Row(mainAxisAlignment:MainAxisAlignment.spaceEvenly,children:const[// 分享入口图标],),),)
  • dismissLabel提供底部关闭按钮文案(如"完成"),不传则无;
  • showCloseButton控制标题栏右上角关闭图标(默认 true);
  • 返回Future<void>,关闭即返回,需要结果的场景用共享 State 或改造为FutureBuilder。

6.2 光感调参

需要更通透或更厚重的半模态时,脱离便捷函数直接用OhosLightMaterial包自己的面板(完整原理见第 7 篇增强类):

// 更通透:模糊与光池减弱OhosLightMaterial(level:OhosLightMaterialLevel.thick,effectTuning:constOhosLightEffectTuning(blurScale:0.8,glowScale:0.6,),child:mySheet,)// 更厚重:开启光感漫射OhosLightMaterial(level:OhosLightMaterialLevel.ultraThick,effectTuning:constOhosLightEffectTuning(scatterScale:0.6),child:mySheet,)

半模态面板实机效果:

showOhosBottomSheet半模态面板:ULTRA_THICK 光感材质 + 底部滑出

七、布局容器 OhosGrid 与 OhosResponsiveBuilder

容器类的"隐藏成员":官方布局规范(栅格/断点)在harmony_ui里由两个布局组件实现。

7.1 栅格 OhosGrid

断点决定列数(<600vp 四列 / 600-840vp 八列 / ≥840vp 十二列),OhosGridItem(columnSpan:)按列跨排布,内容最大宽度 2220vp:

OhosGrid(children:[OhosGridItem(columnSpan:2,child:cardA),OhosGridItem(columnSpan:2,child:cardB),OhosGridItem(columnSpan:4,child:bannerCard),// 通栏],)

7.2 响应式 OhosResponsiveBuilder

OhosResponsiveBuilder依据窗口宽度重建子树,"挪移/折行/分栏"的响应式策略都建立在它之上。回调拿到OhosWindowSize对象,除type外还直接给出当前断点的columns(4/8/12)、margin(16/24/32vp)、gutter(8/12/16vp):

OhosResponsiveBuilder(builder:(context,size){// size.type: compact(<600) / medium(600-840) / large(≥840)returnswitch(size.type){OhosWindowSizeType.compact=>singleColumnLayout,OhosWindowSizeType.medium=>twoColumnLayout,OhosWindowSizeType.large=>sideBySideLayout,};},)
  • size.isCompact/isMedium/isLarge是便捷布尔值,简单判断不用解枚举;
  • size.useSideTab(≥840vp 为 true):宽屏建议切换侧边页签(OhosSideBar,见第 7 篇);
  • size.pagePadding直接返回当前断点的水平内边距,页面根部套一层即可对齐规范。

栅格与断点演示实机效果:

布局与动效:栅格系统、响应式断点(1/2/4 列切换)与沉浸光感入口

八、横滑列表项 OhosListItem

列表项的增强形态——左滑显示操作按钮、整划删除(fullDelete),属于 UI Design Kit 能力,完整用法见第 7 篇增强类,这里给出容器视角的集成方式:

// 在 ListView 里逐行包裹ListView.builder(itemCount:rows.length,itemBuilder:(_,int i)=>OhosListItem(fullDelete:true,onFullDelete:()=>setState(()=>rows.removeAt(i)),actions:[OhosSwipeAction(icon:constIcon(Icons.delete_outline_rounded),backgroundColor:OhosTheme.of(context).dangerColor,onTap:()=>setState(()=>rows.removeAt(i)),),],child:OhosListTile(title:Text(rows[i]),),),)
  • 整划删除阈值、越界自动回调由组件内部处理;
  • 横滑与列表滚动手势的冲突已做仲裁,横向滑动不会被竖向滚动吃掉。

九、在鸿蒙模拟器上运行

容器类全部控件在 gallery 示例应用的「容器」分类页可交互运行,最短运行路径:

  1. 安装3.47.7-ohos-1.0.1的 OH 适配版 SDK。该版本在仓库里是 git tag,按 tag 浅克隆到 fvm 版本目录后在工程内切换:

    gitclone--depth1--branch3.47.7-ohos-1.0.1\https://atomgit.com/oh-flutter/flutter_flutter.git\~/fvm/versions/ohos/oh-3.47.7-releasecd<harmony_ui 仓库根目录>fvm use ohos/oh-3.47.7-release fvm flutter--version# 应输出 Flutter 3.47.7-ohos-1.0.1

    fvm 的fvm install <alias>/<ref>只识别分支名,3.47.7-ohos-1.0.1是 tag,不能直接 install;按上面的方式 clone 到版本目录后fvm use即可。

  2. source env.sh加载 DevEco Studio26.0.0 Release的工具链(node / ohpm / hvigor / SDK toolchains);如果命令不可用,按文首的环境搭建指导检查DEVECO_SDK_HOME、JAVA_HOME与hdc;

  3. 进入example/:fvm flutter pub get && fvm flutter create --platforms ohos .;

  4. 构建并安装到模拟器:

fvm flutter build hap--debug--no-codesign hdc list targets hdcinstall-rbuild/ohos/hap/entry-default-unsigned.hap hdc shell aa start-aEntryAbility-bcom.example.ohos_ui_example

半模态的光感材质依赖BackdropFilter,在模拟器上渲染正常;真机如遇模糊边缘异常,优先关闭scatterScale(漫射)再排查,而不是降模糊档位。

十、最佳实践

容器类控件的选型速查:

场景推荐容器备注
设置页OhosList+OhosSubheader分组短列表直铺
长列表ListView.builder+OhosListTile分页/懒加载
信息流单元OhosCard(24vp 圆角)圆角逐级递减
确认/选择showOhosDialog标题 + 两行内
功能引导showOhosPopup+ 红点状态本地记录
分享/筛选showOhosBottomSheetULTRA_THICK 光感
宽屏网格OhosGrid+OhosGridItem4/8/12 列断点
响应式重构OhosResponsiveBuilder三档断点重建
列表行操作OhosListItem左滑 + 整划删除

实践要点:

  • 第二层空间选型:信息 ≤2 行用对话框,需要操作区/滚动区用半模态,指着控件说用气泡——三层空间各司其职;
  • 卡片零投影:鸿蒙卡片层次靠背景分层(白卡 + 灰底),elevation默认保持 0,投影是 Material 思维;
  • 半模态结果回传:showOhosBottomSheet返回void,需要结果时用全局状态或事件总线,别在content里塞回调地狱;
  • 横滑删除加撤销:onFullDelete后跟一个showOhosSnackBar(撤销),误删成本直接归零;
  • 断点先想清楚:用OhosResponsiveBuilder前先在纸上画三档断点的布局草图,避免代码里堆满if (width > 840)。

十一、常见问题 FAQ

11.1flutter pub get找不到 harmony_ui?

先确认pubspec.yaml写的是harmony_ui: ^0.3.0,或按文首 git 依赖写法固定ref: v0.3.0;pub.dev 与 git 两种方式不要同时声明。改完后执行fvm flutter clean && fvm flutter pub get,仍异常时删除pubspec.lock与.dart_tool/重试,不要手改锁文件。

11.2 组件颜色、字阶与截图不一致?

通常是没有注入主题。OhosTheme要包住页面根节点(MaterialApp.home或builder),组件通过OhosTheme.of(context)读取 Token;只 import 组件库不会自动注入。确认后再检查是否显式覆盖了颜色或字阶参数。

11.3showOhosDialog里 setState 报错或弹窗不关闭?

异步确认后先判断mounted再更新页面状态,并用Navigator.pop(context, result)关闭弹窗;不要在弹窗内容里直接操作已被销毁的页面State。

11.4showOhosBottomSheet怎么把选择结果带回页面?

它返回void,不承载返回值。需要结果时在面板内更新全局状态、Provider/Bloc,或通过事件回调把结果写回页面,别在content里堆回调链。

11.5 卡片内图片圆角看起来不对?

遵循"圆角逐级递减":卡片 24vp > 卡内图片 16–20vp > 图片内元素 8vp。OhosImage默认 8vp,放进卡片时按层级覆盖,不要给整张卡片再套一层裁剪。

11.6OhosListItem左滑与页面横滑手势冲突?

横滑列表项应放在纵向列表内,避免再嵌套横向PageView;同一行只保留一个左滑操作区,整划删除与按钮删除不要同时启用。

11.7 构建时报npm not found、hvigor不存在或DEVECO_SDK_HOME错误?

说明 DevEco 工具链没有进入 PATH。执行source env.sh(按 DevEco Studio 26.0.0 Release 的默认安装路径配置),确认node、ohpm、hvigor、hdc都可执行;DEVECO_SDK_HOME必须指向.../Contents/sdk而不是安装根目录。

11.8 模拟器安装失败,或提示签名错误?

OpenHarmony 模拟器接受未签名 debug HAP:先fvm flutter build hap --debug --no-codesign,再用hdc install -r build/ohos/hap/entry-default-unsigned.hap安装。真机安装与flutter run热重载需要调试证书签名。

11.9 官方 Flutter(Android / iOS / Web)上能用吗?

可以。harmony_ui是纯 Dart/Flutter 实现,不依赖平台通道;字体、光感与模糊的最终效果会随平台渲染能力略有差异。跨平台预览用官方 Flutter 即可,鸿蒙模拟器/真机验证请使用 3.47.7-ohos-1.0.1。

总结

容器类是"壳的艺术":列表装信息、卡片装单元、对话框/半模态/气泡装第二层空间,栅格与断点装响应式。harmony_ui把 24vp 卡片圆角、分组列表行高、ULTRA_THICK 光感半模态这些官方细节都固化成了默认值,六大类别至此全部讲完,加上第 7 篇增强类(沉浸光感 + UI Design Kit),整个harmony_ui的组件版图就完整了。

至此本系列 7 篇全部完结:导航、展示、操作、输入、选择、容器六大类别 + 增强类收官。所有代码可在仓库example/的 gallery 应用中交互验证,欢迎在 OpenHarmony 模拟器上跑起来。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • harmony_ui 仓库(AtomGit):oh-flutter/harmony_ui
  • harmony_ui 仓库(GitHub):shaohushuo/harmony_ui
  • 鸿蒙社区 Flutter 分叉:CPF-Flutter/flutter_flutter
  • 配套图标包 ohos_icons:pub.dev/packages/ohos_icons
  • 官方控件概览(42 控件清单):general_overview
  • 官方布局基础(栅格/断点):design-layout-basics
  • 官方沉浸光感(半模态材质依据):immersivelight
  • fvm 多版本管理:fvm.app

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询