ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Flutter三方库适配OpenHarmony【harmony_ui】选择类控件实战:勾选、单选、开关、评分、滑动条与颜色选择器

Flutter三方库适配OpenHarmony【harmony_ui】选择类控件实战:勾选、单选、开关、评分、滑动条与颜色选择器

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.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是可选配套图标包,不引入也不影响组件使用。

一、选择类总览

官方控件实现一句话说明
勾选框OhosCheckbox多选,圆角边框
单选按钮OhosRadio单选,注意非 groupValue 模式
开关OhosSwitch50×30 胶囊开关
评分条OhosRatingBar星级评分,点击当前星减一
滑动条OhosSlider刻度 + 拖动气泡数值
选择器showOhosPicker底部弹层选择,Future 返回
(增强)分段按钮OhosSegmentedButton2-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 示例应用的「选择」分类页可交互运行,最短运行路径:

  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

10.2 选型速查

场景推荐控件备注
协议勾选OhosCheckbox行内 + 富文本链接
二选一/多选一OhosRadio组非 groupValue 模式
功能开关OhosSwitch设置行尾标配
服务评分OhosRatingBar整数星,再点当前星减一
音量/亮度OhosSlider(divisions + bubble)刻度 + 气泡
连续数值OhosSlider高频回调注意防抖
视图切换(无内容页)OhosSegmentedButton2-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
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进