Flutter三方库适配OpenHarmony【harmony_ui】选择类控件实战:勾选、单选、开关、评分、滑动条与颜色选择器
前言
harmony_ui是 Material/Cupertino 风格的 Flutter 组件库,完整实现了HarmonyOS 设计语言,覆盖官方「控件概览」6 大类 42 个控件,并额外实现了沉浸光感材质与 UI Design Kit 增强能力。本系列按官方控件类别逐类实战:前四篇分别是导航类、展示类、操作类、输入类,本篇是第 5 篇:选择类。
选择类解决的是"从选项里挑"的问题,官方共 6 个控件:勾选框/单选按钮/开关(三件套)、评分条(OhosRatingBar)、滑动条(OhosSlider)、选择器(showOhosPicker),外加颜色选择器(OhosColorPicker)与分段按钮(OhosSegmentedButton)两个增强项。这一类控件的 API 与 Flutter 内置组件高度一致,但单选按钮的签名与 Material 不同(不是 groupValue 模式),迁移时要特别注意。
所有示例代码都在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是可选配套图标包,不引入也不影响组件使用。
一、选择类总览
| 官方控件 | 实现 | 一句话说明 |
|---|---|---|
| 勾选框 | OhosCheckbox | 多选,圆角边框 |
| 单选按钮 | OhosRadio | 单选,注意非 groupValue 模式 |
| 开关 | OhosSwitch | 50×30 胶囊开关 |
| 评分条 | OhosRatingBar | 星级评分,点击当前星减一 |
| 滑动条 | OhosSlider | 刻度 + 拖动气泡数值 |
| 选择器 | showOhosPicker | 底部弹层选择,Future 返回 |
| (增强)分段按钮 | OhosSegmentedButton | 2-N 段互斥切换 |
| (增强)颜色选择器 | OhosColorPicker | 网格/光谱/滑块三模式 + 收藏 |
选择类整体效果(gallery「选择」分类页,模拟器实机):
选择类:勾选/单选/开关三件套、星级评分、带气泡数值的滑动条、分段按钮、颜色选择器与底部选择器
二、勾选框 OhosCheckbox
2.1 基本用法
OhosCheckbox是圆角边框复选框,选中时品牌色填充 + 白色对勾,与 Material 的方框风格略有不同:
OhosCheckbox(value:_agreed,onChanged:(bool v)=>setState(()=>_agreed=v),)onChanged: null即禁用态(灰化不可点);activeColor可覆盖选中色(默认品牌色#0A59F7);size默认 24vp。
2.2 与列表项组合
"协议勾选"是勾选框最高频的场景,放在列表项行尾或页面底部:
Row(children:[OhosCheckbox(value:_agreed,onChanged:(bool v)=>setState(()=>_agreed=v),),constSizedBox(width:8),Expanded(child:RichText(text:TextSpan(text:'我已阅读并同意',style:TextStyle(fontSize:13,color:Colors.black54),children:const[TextSpan(text:'《用户协议》',style:TextStyle(color:Color(0xFF0A59F7))),TextSpan(text:'与',style:TextStyle(color:Colors.black54)),TextSpan(text:'《隐私政策》',style:TextStyle(color:Color(0xFF0A59F7))),],),),),],)三、单选按钮 OhosRadio
3.1 单选组
注意:
OhosRadio的签名与 Flutter 的Radio<T>不同——它是"单实例布尔值"模式(value: bool),不是 groupValue 模式。每个单选按钮自己判断自己是否被选中,选中逻辑由业务层维护。
class_PlanPageStateextendsState<PlanPage>{String_plan='month';Widget_radioRow(Stringvalue,Stringlabel){returnInkWell(onTap:()=>setState(()=>_plan=value),child:Row(children:[OhosRadio(value:_plan==value,// 自己是否选中onChanged:(bool _)=>setState(()=>_plan=value),),constSizedBox(width:8),Text(label),],),);}@overrideWidgetbuild(BuildContextcontext){returnColumn(children:[_radioRow('month','包月 ¥ 30/月'),_radioRow('year','包年 ¥ 300/年'),],);}}3.2 与列表组合
单选组放进OhosList是设置页的标准形态(如"通知方式"选择):
OhosList(header:constOhosSubheader(title:'通知方式'),children:[for(final(value,label)inconst[('push','应用内推送'),('sms','短信'),('email','邮件'),])OhosListTile(title:Text(label),trailing:OhosRadio(value:_notify==value,onChanged:(bool _)=>setState(()=>_notify=value),),onTap:()=>setState(()=>_notify=value),),],)- 整行可点(
onTap)比只点圆圈更符合移动操作习惯,建议保留; - 单选组互斥逻辑在业务层:选中 A 时 B/C 的
value自然变 false。
四、开关 OhosSwitch
4.1 设置行
OhosSwitch是 50×30vp 胶囊开关,设置页行尾标配,支持自定义开/关颜色:
OhosSwitch(value:_darkMode,onChanged:(bool v)=>setState(()=>_darkMode=v),activeColor:constColor(0xFF0A59F7),inactiveColor:constColor(0xFFC7C7CC),)4.2 典型设置页
设置页的完整组合(开关 + 单选 + 跳转行混排):
OhosList(header:constOhosSubheader(title:'通用'),children:[OhosListTile(leading:constIcon(Icons.dark_mode_outlined),title:constText('深色模式'),trailing:OhosSwitch(value:_dark,onChanged:_onDarkMode),),constOhosDivider(),OhosListTile(leading:constIcon(Icons.notifications_none),title:constText('免打扰'),trailing:OhosSwitch(value:_dnd,onChanged:_dndEnabled?_onDnd:null,// 未开启推送时禁用),),constOhosDivider(),OhosListTile(leading:constIcon(Icons.language),title:constText('系统语言'),trailing:constIcon(Icons.chevron_right),onTap:_openLanguage,),],)五、评分条 OhosRatingBar
OhosRatingBar星级评分:value为整数星数,onChanged可交互(传null则只读展示):
// 可交互:点第几颗给几分OhosRatingBar(value:_rating,onChanged:(int v)=>setState(()=>_rating=v),starSize:32,)// 只读展示:商品详情页OhosRatingBar(value:4,onChanged:null,count:5,starSize:20)- 再次点击当前星会减一(点第 4 颗已是 4 分时再点回到 3 分),与鸿蒙应用行为一致;
count默认 5,支持非 5 星制(如 10 分制评价);- 颜色默认品牌色(选中)/ 20% 灰(未选中),
activeColor/inactiveColor可覆盖。
注意:
OhosRatingBar是整数星,不支持半星。需要 4.5 分展示的详情页,用"整数星 + 文字 4.5"组合,或用只读评分条 + 数字文案。
六、滑动条 OhosSlider
6.1 带刻度
OhosSlider支持divisions刻度(音量、亮度场景),拖动时值吸附到刻度:
OhosSlider(value:_volume,onChanged:(double v)=>setState(()=>_volume=v),min:0,max:100,divisions:20,// 20 段刻度label:'音量',// 可选标签)6.2 拖动气泡数值
showValueBubble: true开启拖动气泡:拖动时拇指上方浮出当前数值,松手消失——鸿蒙应用音量条的标志性交互:
OhosSlider(value:_brightness,onChanged:(double v)=>setState(()=>_brightness=v),min:20,max:100,divisions:10,showValueBubble:true,)enabled: false整体禁用(灰化),如"亮度跟随系统"时禁用手动条;activeColor覆盖已滑过区间的颜色;- 连续
onChanged高频触发:亮度/音量场景即时应用没问题,网络请求场景要防抖(同输入类搜索框的思路)。
七、分段按钮 OhosSegmentedButton
2-N 段互斥切换(视图切换"日/周/月"、列表模式"列表/宫格"),泛型T与选择器同款:
OhosSegmentedButton<String>(segments:const[OhosSegment(label:'日',value:'day'),OhosSegment(label:'周',value:'week'),OhosSegment(label:'月',value:'month'),],selected:_view,onSelected:(Stringv)=>setState(()=>_view=v),)- 选中段品牌色高亮,与胶囊子页签(
OhosTabBar(type: capsule))视觉同源; - 与子页签的分工:分段按钮不挂内容页(纯切换控件),子页签驱动 TabBarView 内容;2-4 段切换用分段按钮,带内容页的切换用子页签。
八、颜色选择器 OhosColorPicker
8.1 三种模式
OhosColorPicker提供网格 / 光谱 / 滑块三种选色模式(OhosColorPickerTab),通过tabs参数决定显示哪些模式页签:
OhosColorPicker(colors:const[Color(0xFF0A59F7),Color(0xFF64BB5C),Color(0xFFE84026),Color(0xFFF7B500),Color(0xFF8B5CF6),],selectedColor:_color,onChanged:(Colorc)=>setState(()=>_color=c),tabs:const[OhosColorPickerTab.grid,// 网格:预设色块OhosColorPickerTab.spectrum,// 光谱:色相条选色OhosColorPickerTab.sliders,// 滑块:RGB 通道调节],)三种模式的适用场景:
| 模式 | 交互 | 场景 |
|---|---|---|
grid网格 | 点预设色块 | 主题色选择(有限候选) |
spectrum光谱 | 色相条 + 明度面 | 自由选色 |
sliders滑块 | RGB 三通道 | 精确取色/调参 |
8.2 收藏管理
favoriteColors+onFavoritesChanged支持收藏色板:常用颜色置顶管理,与 UI Design Kit 颜色选择器能力对齐:
OhosColorPicker(colors:palette,selectedColor:_color,onChanged:_onColorChanged,favoriteColors:_favorites,onFavoritesChanged:(List<Color>colors)=>setState(()=>_favorites=colors),tabs:const[OhosColorPickerTab.grid,OhosColorPickerTab.spectrum],)颜色选择器实机效果(光谱模式选中态):
OhosColorPicker光谱模式:色相条选色 + 当前选中色预览
九、底部选择器 showOhosPicker
9.1 单选
showOhosPicker弹出底部面板做列表选择,Future<T?>返回选中值,与 Flutter 的showModalBottomSheet习惯一致:
finalString?city=awaitshowOhosPicker<String>(context:context,title:'选择城市',initialValue:_city,// 当前值回显items:const[OhosPickerItem(label:'北京',value:'beijing'),OhosPickerItem(label:'上海',value:'shanghai'),OhosPickerItem(label:'深圳',value:'shenzhen'),],);if(city!=null)setState(()=>_city=city);9.2 带副标题
OhosPickerItem支持subtitle第二行小字(城市 + 省份、联系人 + 部门):
finalint?contact=awaitshowOhosPicker<int>(context:context,title:'选择联系人',items:[OhosPickerItem(label:'张三',subtitle:'产品部',value:1),OhosPickerItem(label:'李四',subtitle:'研发部',value:2),OhosPickerItem(label:'王五',subtitle:'设计部',value:3),],);- 取消(点遮罩/下滑)返回
null,与选中值区分开处理; - 选项多时底部面板自带滚动,无需分页。
十、在鸿蒙模拟器上运行与最佳实践
10.1 模拟器运行
选择类全部控件在 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_example10.2 选型速查
| 场景 | 推荐控件 | 备注 |
|---|---|---|
| 协议勾选 | OhosCheckbox | 行内 + 富文本链接 |
| 二选一/多选一 | OhosRadio组 | 非 groupValue 模式 |
| 功能开关 | OhosSwitch | 设置行尾标配 |
| 服务评分 | OhosRatingBar | 整数星,再点当前星减一 |
| 音量/亮度 | OhosSlider(divisions + bubble) | 刻度 + 气泡 |
| 连续数值 | OhosSlider | 高频回调注意防抖 |
| 视图切换(无内容页) | OhosSegmentedButton | 2-4 段 |
| 视图切换(带内容页) | OhosTabBar(capsule) | 导航类篇 |
| 主题色/有限候选 | OhosColorPicker(grid) | 可加收藏 |
| 自由取色 | OhosColorPicker(spectrum/sliders) | 光谱 + 滑块 |
| 列表选择(常驻) | OhosSelect | 操作类篇,选项 ≤5 |
| 列表选择(弹层) | showOhosPicker | 选项多、带副标题 |
10.3 实践要点
- 三件套别混用:多选 Checkbox、单选 Radio、开关 Switch 语义严格分开——"启用/关闭"永远用 Switch,不要用 Checkbox 当开关;
- 单选组整行可点:
OhosListTile(onTap:)+ 行尾OhosRadio,点击热区比只点圆圈大得多; - 禁用态传 null:三件套统一
onChanged: null禁用,配合主题灰化,不需要自己包Opacity; - 评分条只读场景传 null:
onChanged: null的评分条是纯展示,详情页大量使用; - 滑块高频回调:
OhosSlider拖动期间每帧回调,网络类副作用放onChanged外的"松手"时机(可结合Listenable或业务节流)。
十一、常见问题 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.3OhosRadio为什么没有groupValue?
它刻意采用"单实例布尔值"模式:value表示自己是否选中,互斥逻辑由业务层维护(选中 A 时把 B/C 的value置为false)。直接照搬 FlutterRadio<T>的 groupValue 写法会编译不过。
11.4OhosRatingBar支持半星吗?
不支持,它按整数星计数。需要展示 4.5 分时,用"整数星 + 文字 4.5"组合,或使用只读评分条配数字文案,不要试图通过starSize模拟半星。
11.5OhosColorPicker三种模式怎么选?
网格模式适合预设色板,光谱模式适合自由取色,滑块模式适合精确调 RGB/HSV;三种模式共用同一套value/onChanged,切换模式不会丢失当前颜色。
11.6showOhosPicker取消后返回什么?
取消(点遮罩或下滑)返回null,与选中值区分开处理;选项较多时面板自带滚动,不需要分页,也不要把null当成某个默认选项。
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把每种形态都做到了官方规范的默认值水平,业务侧唯一要留神的是OhosRadio的非 groupValue 签名——迁移 Material 代码时这一处必须手动改。
下一篇进入容器类:列表/列表项、卡片、弹出框、气泡提示与光感半模态面板,把"装内容的壳"讲全,六大类别系列到此收官(增强类见第 7 篇)。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- 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
- 官方色彩 Token 文档(颜色选择器色板依据):color
- fvm 多版本管理:fvm.app