前言
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.1 | oh-flutter/flutter_flutter,oh-3.47-dev分支 |
| DevEco Studio | 26.0.0 Release | 提供 hvigor / ohpm / hdc / JBR 等工具链 |
| OpenHarmony SDK / API | API 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 getpub.dev 与 git 两种方式二选一,不要同时声明。CI 中建议固定 tag(如
v0.3.0)而不是main,避免构建结果随上游漂移。harmony_ui目前只依赖qr一个三方包,ohos_icons是可选配套图标包,不引入也不影响组件使用。
一、容器类总览
| 官方控件 | 实现 | 一句话说明 |
|---|---|---|
| 列表 / 列表项 | OhosList/OhosListTile | 分组列表,选中态/危险项 |
| 卡片 | OhosCard | 24vp 大圆角,按压反馈 |
| 弹出框 | OhosAlertDialog/showOhosDialog | 双按钮确认,危险操作红色 |
| 气泡提示 | showOhosPopup | 锚定控件的功能引导 |
| 半模态面板 | showOhosBottomSheet | ULTRA_THICK 光感材质 |
| (布局容器)栅格/响应式 | OhosGrid/OhosResponsiveBuilder | 4/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 示例应用的「容器」分类页可交互运行,最短运行路径:
安装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.1fvm 的
fvm install <alias>/<ref>只识别分支名,3.47.7-ohos-1.0.1是 tag,不能直接 install;按上面的方式 clone 到版本目录后fvm use即可。source env.sh加载 DevEco Studio26.0.0 Release的工具链(node / ohpm / hvigor / SDK toolchains);如果命令不可用,按文首的环境搭建指导检查DEVECO_SDK_HOME、JAVA_HOME与hdc;进入
example/:fvm flutter pub get && fvm flutter create --platforms ohos .;构建并安装到模拟器:
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+ 红点 | 状态本地记录 |
| 分享/筛选 | showOhosBottomSheet | ULTRA_THICK 光感 |
| 宽屏网格 | OhosGrid+OhosGridItem | 4/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