news 2026/7/14 2:18:21

HarmonyOS智能家居——设置页面的分组菜单与开关交互

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS智能家居——设置页面的分组菜单与开关交互

设置页面是智能家居 App 里菜单项最多的页面——三组菜单共 12 个选项,其中 5 个是可切换的开关,7 个是跳转链接。从截图看,页面分四个区域:顶部用户卡片、设备管理(3 项链接)、偏好设置(5 项开关)、系统(4 项链接),底部有一个红色的"退出登录"按钮。实现上用了三个 Builder(Link、Toggle、Div),把菜单项的两种形态——可跳转的链接和可切换的开关——分别抽象成了独立的 Builder。
完整效果

数据结构

@StatenotifyOn:boolean=true@StatedarkMode:boolean=false@StateautoUpdate:boolean=true@StatevoiceWake:boolean=true@StateenergySave:boolean=false

五个@State布尔值分别控制五个开关的状态。每个开关都是独立的——修改"通知提醒"不会影响"深色模式"。这种"每个开关一个变量"的做法虽然啰嗦(5 个变量),但最直观,新手也能看懂。

更紧凑的做法是用一个对象管理所有开关:

@Statesettings:Record<string,boolean>={notify:true,darkMode:false,autoUpdate:true,voiceWake:true,energySave:false}

但 ArkTS 里Record的属性修改不会自动触发@State刷新,需要额外处理。在当前规模下,5 个独立变量是更稳妥的选择。

用户卡片

Row(){Stack(){Column(){}.width(50).height(50).borderRadius(25).linearGradient({angle:135,colors:[[A,0],['#A78BFA',1]]})Text('🏠').fontSize(22)}Column(){Text('我的家').fontSize(16).fontWeight(FontWeight.Bold).fontColor(T1)Text('5个房间 · 17台设备').fontSize(12).fontColor(T3).margin({top:2})}.alignItems(HorizontalAlign.Start).margin({left:14}).layoutWeight(1)SymbolGlyph($r('sys.symbol.chevron_right')).fontSize(14).fontColor(['#DDD'])}.width('100%').padding(18).backgroundColor('#FFFFFF').borderRadius(18).margin({left:16,right:16,bottom:16}).onClick(()=>{router.pushUrl({url:'pages/RoomPage',params:{'room':'客厅'}asRecord<string,Object>})})

用户卡片的结构和运动健康 App、旅行 App 的个人中心卡片一致——左侧渐变圆头像 + 中间文字 + 右侧箭头。点击后跳转到 RoomPage,默认显示客厅。

"5个房间 · 17台设备"是硬编码的——没有从ROOMS.lengthDEVICES.length动态计算。如果以后数据变化,需要手动更新这个字符串。更好的做法是动态拼接:

Text(ROOMS.length+'个房间 · '+DEVICES.length+'台设备')

但在原型阶段,写死更省事。

三组菜单的分组结构

// 设备管理Column({space:0}){Text('设备管理').fontSize(12).fontWeight(FontWeight.Bold).fontColor(T3).width('100%').padding(14).padding({bottom:4})this.Link('🏠','家庭管理','管理房间和设备',()=>{...})this.Div()this.Link('🔊','语音助手','小爱同学 · 已连接',()=>{...})this.Div()this.Link('🔌','添加设备','扫描附近的新设备',()=>{...})}

每组菜单用一个Column({ space: 0 })包裹,顶部是灰色的组标题(12px、T3 颜色),下方是菜单项列表。space: 0保证菜单项之间没有额外间距——间距由 Div 分割线控制。

组标题用fontSize(12)+fontWeight(Bold)+fontColor(T3),视觉上比菜单项更小更淡,形成明确的主次关系。标题下方的padding({ bottom: 4 })给标题和第一个菜单项之间留了一点呼吸空间。

菜单项的两种形态

设备管理和系统组用的是Link(带右箭头的跳转链接),偏好设置组用的是Toggle(带开关状态的切换项)。两种形态的视觉结构几乎一样——左侧 emoji + 中间文字(标题 + 副标题),区别只在右侧:

  • Link:灰色右箭头(SymbolGlyph
  • Toggle:绿色"开"或灰色"关"文字

Link Builder

@BuilderLink(icon:string,label:string,sub:string,action:()=>void){Row(){Text(icon).fontSize(18).margin({right:12})Column(){Text(label).fontSize(14).fontColor(T1)Text(sub).fontSize(11).fontColor(T3).margin({top:1})}.alignItems(HorizontalAlign.Start).layoutWeight(1)SymbolGlyph($r('sys.symbol.chevron_right')).fontSize(12).fontColor(['#DDD'])}.width('100%').padding({left:14,right:14,top:12,bottom:12}).onClick(action)}

四个参数:图标、标题、副标题、回调。副标题用 T3 颜色(#BBBBBB)和 11px 字号,比标题(T1、14px)更淡更小,形成信息层次。右箭头用系统 SymbolGlyph 而不是 emoji,视觉上更规范。

Toggle Builder

@BuilderToggle(icon:string,label:string,sub:string,on:boolean,action:()=>void){Row(){Text(icon).fontSize(18).margin({right:12})Column(){Text(label).fontSize(14).fontColor(T1)Text(sub).fontSize(11).fontColor(T3).margin({top:1})}.alignItems(HorizontalAlign.Start).layoutWeight(1)Text(on?'🟢 开':'⚫ 关').fontSize(12).fontColor(on?A:T3)}.width('100%').padding({left:14,right:14,top:12,bottom:12}).onClick(action)}

五个参数:图标、标题、副标题、开关状态、回调。比 Link 多了一个on参数,控制右侧显示"🟢 开"还是"⚫ 关"。

开关状态文字的颜色也跟随变化——开启时用主色(#6C5CE7),关闭时用 T3 灰色。这让开关状态不只是文字不同,颜色也提供了视觉反馈。

和原生 Toggle 组件的区别

HarmonyOS 有内置的Toggle组件,但这里没有用。原因是内置 Toggle 的样式比较固定——一个滑块在圆形轨道上左右滑动。而这个页面的开关用文字(“开”/“关”)+ emoji 圆点来表示,视觉上更轻量,和菜单项的文字风格更协调。

在需要"安静"的设置页面里,文字开关比滑块开关更不抢眼——用户扫一眼就能看到哪些开着哪些关着,不需要辨认滑块的位置。

分割线 Div Builder

@BuilderDiv(){Divider().strokeWidth(0.5).color('#F0EEF4').margin({left:56})}

分割线从左侧 56px 开始——跳过了 emoji 图标(18px)+ 右边距(12px)+ 一点余量,让分割线从文字区域开始,不会穿过图标。这个margin({ left: 56 })的值和运动健康 App、旅行 App 里的分割线处理方式一致。

strokeWidth(0.5)是最细的分割线——0.5vp 在高分辨率屏幕上几乎是一条细线,既能分隔菜单项,又不会太显眼。

退出登录按钮

Row(){Text('退出登录').fontSize(15).fontWeight(FontWeight.Bold).fontColor('#FF6B6B')}.width('100%').height(50).backgroundColor('#FFFFFF').borderRadius(18).justifyContent(FlexAlign.Center).margin({left:16,right:16,bottom:30}).onClick(()=>{router.back()})

红色文字、居中对齐、独立的白色卡片。点击后只是router.back()——没有实际的退出登录逻辑,只是一个 UI 占位。

按钮用justifyContent(FlexAlign.Center)让文字水平居中,和菜单项的左对齐形成对比。视觉上,退出按钮和其他菜单项明显不同——它不是"菜单里的一项",而是"独立的操作"。

三组菜单的功能映射

分组菜单项类型点击行为
设备管理家庭管理Link跳转 RoomPage
设备管理语音助手Link切换 voiceWake
设备管理添加设备Link跳转 RoomPage
偏好设置通知提醒Toggle切换 notifyOn
偏好设置深色模式Toggle切换 darkMode
偏好设置自动更新Toggle切换 autoUpdate
偏好设置语音唤醒Toggle切换 voiceWake
偏好设置节能模式Toggle切换 energySave
系统网络设置Link跳转 RoomPage
系统固件更新Link跳转 SecurityPage
系统数据统计Link跳转 EnergyPage
系统关于Linkrouter.back()

12 个菜单项中,只有 5 个有实际的状态切换逻辑(偏好设置组),其他 7 个要么跳转到已有页面,要么是空操作。这种"少数真实、多数占位"的分布是设置页面的典型状态——先把菜单结构搭好,功能后面逐步填充。

语音助手的特殊行为

语音助手在设备管理组里用的是 Link 样式(有右箭头),但点击行为是切换voiceWake状态——和偏好设置里的"语音唤醒"切换的是同一个变量。这意味着点击"语音助手"会同时影响两个菜单项的显示状态,因为它们共享@State voiceWake

这种"两个菜单项控制同一个状态"的设计在实际 App 里不太常见,但在原型阶段可以接受——它演示了@State变量可以在不同 Builder 之间共享。

设置页面和其他页面的状态差异

设置页面的@State变量和其他页面有一个关键区别——它们的修改不会影响其他页面:

  • 修改notifyOn不会影响首页的任何显示
  • 修改darkMode不会真的切换深色主题
  • 修改energySave不会影响设备的实际能耗

这是因为这些开关目前只控制页面内的显示状态,没有接入真实的功能逻辑。在真正的 App 里,darkMode需要切换全局主题,energySave需要修改设备的运行参数,notifyOn需要控制系统的通知权限。这些功能需要通过服务层或全局状态管理来实现,不能只靠页面内的@State

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 2:18:01

C#调用C++ DLL完整指南:从P/Invoke到生产环境实战

1. 项目概述&#xff1a;为什么C#开发者绕不开C DLL&#xff1f;在Windows平台上做C#开发&#xff0c;尤其是涉及到上位机、工业控制、图像处理或者性能敏感的计算模块时&#xff0c;你迟早会遇到一个场景&#xff1a;手头有一个现成的、用C写的、性能强悍或者功能专一的动态链…

作者头像 李华
网站建设 2026/7/14 2:16:55

照片修复全攻略:从曝光校正到AI智能修复的完整流程

拯救废片就像呼吸一样简单&#xff1a;从基础到精通的照片修复全攻略在数字摄影时代&#xff0c;我们每天都会拍摄大量照片&#xff0c;但总有一些因为各种原因变成了"废片"——曝光不足、对焦模糊、色彩失真&#xff0c;或是构图不佳。传统观念认为这些照片只能被删…

作者头像 李华
网站建设 2026/7/14 2:16:39

qwen2.5vl学习

qwen2.5vl通过增强的视觉识别&#xff0c;精确的目标定位&#xff0c;强大的文档解析和长视频理解&#xff0c;在理解和与世界交互方面实现了重大飞跃突出特性&#xff1a;能够使用边界框或点准确地定位物体。它可以从发票、表格和表单中提取结构化数据&#xff0c;以及对图表、…

作者头像 李华
网站建设 2026/7/14 2:15:43

Python国密SM2算法实战:基于GmSSL的完整实现与避坑指南

1. 项目概述&#xff1a;为什么你需要一个靠谱的SM2 Python实现如果你正在用Python处理需要国密算法的项目&#xff0c;比如对接某个银行的支付接口、开发政务系统&#xff0c;或者仅仅是出于合规要求&#xff0c;那你大概率已经经历过“到处找代码”的痛苦了。网上关于SM2的代…

作者头像 李华
网站建设 2026/7/14 2:15:28

STM32与NAU8224构建高效音频系统详解

1. NAU8224与STM32L041C6的音频系统架构解析NAU8224是Nuvoton公司推出的一款高效Class-D音频功率放大器芯片&#xff0c;采用先进的PWM调制技术&#xff0c;能够提供高达3W的输出功率。这款芯片最显著的特点是集成了I2C控制接口&#xff0c;允许开发者通过数字方式精细调节增益…

作者头像 李华