当前位置: 首页 > news >正文

鸿蒙Next实战开发(四):个人中心与系统设置页面开发

鸿蒙Next实战开发(四):个人中心与系统设置页面开发

系列第四篇,我们来实现"智慧生活"App的最后两个页面——个人中心和数据设置页。包含头像卡片、数据统计、功能菜单、Toggle开关、字体选择、AlertDialog弹窗等交互。


一、页面概览

本篇覆盖两个页面:

页面文件用途
👤 个人中心Index.etsProfileContent用户信息、数据统计、功能入口
⚙️ 系统设置SettingsPage.ets显示/通知/数据设置、关于信息

二、个人中心模块

个人中心是 Tabs 底部导航的第四个 Tab,作为用户个人信息的聚合入口。

2.1 整体布局

┌─────────────────────────┐ │ 👤 │ ← 头像 │ HarmonyOS 开发者 │ ← 昵称 │ 探索智慧生活,连接无限可能 │ ← 签名 ├──────┬──────┬──────────┤ │ 📝 │ ✅ │ 📅 │ ← 数据统计 │ 5 │ 6 │ 7天 │ │ 笔记 │ 待办 │ 连续 │ ├──────┴──────┴──────────┤ │ 功能设置 │ │ 🌙 深色模式 跟随系统 ›│ ← 菜单列表 │ 🔔 消息通知 已开启 ›│ │ 🔒 隐私设置 ›│ │ ⚙️ 系统设置 ›│ ← 可跳转 │ 📖 使用帮助 ›│ │ ℹ️ 关于应用 v1.0.0 ›│ └─────────────────────────┘

2.2 头像与个人信息

使用 emoji 做轻量头像(避免加载图片资源的复杂性):

// 头像Column(){Text('👤').fontSize(52);}.width(80).height(80).backgroundColor('#FFE8F0FE').borderRadius(40).alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center);Text('HarmonyOS 开发者').fontSize(18).fontWeight(FontWeight.Bold).fontColor($r('app.color.text_primary'));Text('探索智慧生活,连接无限可能').fontSize(14).fontColor($r('app.color.text_tertiary'));

2.3 数据统计三卡片

通过@Builder buildStatCard复用卡片样式:

@BuilderbuildStatCard(icon:string,label:string,value:string){Column({space:6}){Text(icon).fontSize(24);Text(value).fontSize(18).fontWeight(FontWeight.Bold).fontColor($r('app.color.text_primary'));Text(label).fontSize(12).fontColor($r('app.color.text_tertiary'));}.layoutWeight(1).padding(16).backgroundColor($r('app.color.card_background')).borderRadius(16).shadow({radius:4,color:'#0A000000',offsetY:1}).alignItems(HorizontalAlign.Center);}

使用:

Row({space:12}){this.buildStatCard('📝','笔记','5');this.buildStatCard('✅','待办','6');this.buildStatCard('📅','连续','7天');}.width('100%').padding({left:16,right:16});

2.4 功能菜单列表

在 ArkTS 中,我们可以编写多个@Builder来处理不同类型的菜单项:

普通菜单项(仅展示):

@BuilderbuildMenuItem(icon:string,label:string,detail:string){Row(){Text(icon).fontSize(22);Text(label).fontSize(16).fontColor($r('app.color.text_primary')).margin({left:12}).layoutWeight(1);if(detail.length>0){Text(detail).fontSize(14).fontColor($r('app.color.text_tertiary'));}Text('›').fontSize(22).fontColor($r('app.color.text_tertiary')).margin({left:8});}.width('100%').padding({top:14,bottom:14});}

带路由跳转的菜单项

@BuilderbuildMenuLinkItem(icon:string,label:string,detail:string){Row(){Text(icon).fontSize(22);Text(label).fontSize(16).fontColor($r('app.color.text_primary')).margin({left:12}).layoutWeight(1);if(detail.length>0){Text(detail).fontSize(14).fontColor($r('app.color.text_tertiary'));}Text('›').fontSize(22).fontColor($r('app.color.text_tertiary')).margin({left:8});}.width('100%').padding({top:14,bottom:14}).onClick(()=>{router.pushUrl({url:'pages/SettingsPage'});});}

为什么拆分两个 Builder?因为 ArkTS 的@Builder函数不支持条件判断路由跳转——如果点击事件需要区分不同行为,要么拆分 Builder,要么传入回调函数。

使用方式:

Column({space:1}){this.buildMenuItem('🌙','深色模式','跟随系统');this.buildMenuItem('🔔','消息通知','已开启');this.buildMenuItem('🔒','隐私设置','');this.buildMenuLinkItem('⚙️','系统设置','');this.buildMenuItem('📖','使用帮助','');this.buildMenuItem('ℹ️','关于应用','v1.0.0');}.width('100%').backgroundColor($r('app.color.card_background')).borderRadius(16).shadow({radius:4,color:'#0A000000',offsetY:1}).padding({left:16,right:16});

三、系统设置页面

3.1 功能清单

系统设置页是独立路由页面,通过router.pushUrl跳转进入,包含:

区域功能交互组件
显示设置深色模式Toggle 开关
显示设置字体大小(小/中/大)点击选择
通知设置消息通知Toggle 开关
通知设置声音提醒Toggle 开关
通知设置震动反馈Toggle 开关
数据存储自动同步Toggle 开关
数据存储清除缓存AlertDialog 确认
数据存储导出数据点击
关于应用版本/构建版本/开源许可展示

3.2 顶部导航栏

Row(){Text('← 返回').fontSize(16).fontColor($r('app.color.primary_color')).onClick(()=>{router.back();});Blank();Text('系统设置').fontSize(18).fontWeight(FontWeight.Bold).fontColor($r('app.color.text_primary'));Blank();Row().width(50);// 占位保持对称}

3.3 Toggle 开关组件

鸿蒙的Toggle组件支持三种类型:SwitchCheckboxButton

构建可复用的开关行

@BuilderbuildToggleItem(icon:string,label:string,checked:boolean,onChange:(value:boolean)=>void){Row(){Text(icon).fontSize(22);Text(label).fontSize(16).fontColor($r('app.color.text_primary')).margin({left:12}).layoutWeight(1);Toggle({type:ToggleType.Switch,isOn:checked}).onChange((value:boolean)=>{onChange(value);});}.width('100%').padding({top:10,bottom:10});}

使用:

this.buildToggleItem('🌙','深色模式',this.darkMode,(value:boolean)=>{this.darkMode=value;});this.buildToggleItem('🔔','消息通知',this.notificationEnabled,(value:boolean)=>{this.notificationEnabled=value;});

3.4 字体大小选择

使用三个标签按钮实现单选效果:

@BuilderbuildSizeOption(label:string,value:number){Text(label).fontSize(12).fontColor(this.fontSize===value?Color.White:$r('app.color.text_primary')).backgroundColor(this.fontSize===value?$r('app.color.primary_color'):'#FFF3F4F6').padding({left:12,right:12,top:4,bottom:4}).borderRadius(12).onClick(()=>{this.fontSize=value;});}

使用:

Row({space:4}){this.buildSizeOption('小',0);this.buildSizeOption('中',1);this.buildSizeOption('大',2);}

3.5 AlertDialog 确认弹窗

当用户点击"清除缓存"时,弹出确认对话框:

this.buildClickItem('🗑️','清除缓存','12.5 MB',()=>{AlertDialog.show({title:'清除缓存',message:'确定要清除所有缓存数据吗?',primaryButton:{value:'取消',action:()=>{}},secondaryButton:{value:'确定',action:()=>{// 执行清除操作}},cancel:()=>{}});});

AlertDialog.show的参数配置:

参数类型说明
titlestring弹窗标题
messagestring弹窗内容
primaryButtonobject主按钮(左侧)
secondaryButtonobject次按钮(右侧)
cancelfunction点击遮罩层或按返回键的回调

3.6 可点击的菜单项

@BuilderbuildClickItem(icon:string,label:string,detail:string,onClick:()=>void){Row(){Text(icon).fontSize(22);Text(label).fontSize(16).fontColor($r('app.color.text_primary')).margin({left:12}).layoutWeight(1);if(detail.length>0){Text(detail).fontSize(14).fontColor($r('app.color.text_tertiary')).margin({right:8});}Text('›').fontSize(22).fontColor($r('app.color.text_tertiary')).margin({left:4});}.width('100%').padding({top:14,bottom:14}).onClick(()=>{onClick();});}

3.7 信息展示项

@BuilderbuildInfoItem(icon:string,label:string,value:string){Row(){Text(icon).fontSize(22);Text(label).fontSize(16).fontColor($r('app.color.text_primary')).margin({left:12}).layoutWeight(1);Text(value).fontSize(14).fontColor($r('app.color.text_tertiary'));}.width('100%').padding({top:14,bottom:14});}

3.8 分区布局

设置页面按功能分区组织,每个分区有标题和卡片容器:

// 显示设置Text('显示设置').fontSize(16).fontWeight(FontWeight.Medium);Column({space:0}){this.buildToggleItem('🌙','深色模式',this.darkMode,...);this.buildDivider();// 字体大小行}.backgroundColor($r('app.color.card_background')).borderRadius(16).padding({left:16,right:16});// 分割线@BuilderbuildDivider(){Row().width('100%').height(1).backgroundColor($r('app.color.divider_color'));}

每个分区间的Text标题 +Column卡片容器 构成清晰的视觉分组。


四、状态管理:多个 @State 变量协

设置页有 6 个@State变量管理不同的设置项:

@StatedarkMode:boolean=false;@StatenotificationEnabled:boolean=true;@StatesoundEnabled:boolean=true;@StatevibrationEnabled:boolean=true;@StateautoSync:boolean=false;@StatefontSize:number=1;

每个Toggle组件的onChange回调直接更新对应的@State变量,ArkUI 框架会自动追踪变化并触发重新渲染。

这种模式称为“状态驱动UI”——开发者只管理状态,UI 由框架自动更新。


五、@Builder 传回调函数模式

本篇文章中多次使用了传入回调函数的 Builder 模式,这是 ArkTS 中实现组件复用和交互分离的关键技巧:

// 定义:接收 onChange 回调@BuilderbuildToggleItem(icon:string,label:string,checked:boolean,onChange:(value:boolean)=>void// ← 回调函数类型){Toggle({type:ToggleType.Switch,isOn:checked}).onChange((value:boolean)=>{onChange(value);});}// 使用:传入具体的回调实现this.buildToggleItem('🌙','深色模式',this.darkMode,(value:boolean)=>{this.darkMode=value;// 更新状态变量});

这种模式的好处:

  1. Builder 无状态:它不知道也不关心状态如何变化
  2. 调用者控制逻辑:由使用方决定回调中做什么
  3. 高度复用:同一个 Builder 可以在不同场景使用

六、本篇小结

本篇我们实现了:

  1. 个人中心页面:头像 + 统计卡片 + 功能菜单列表
  2. 系统设置页面:Toggle 开关 + 字体选择 + 分区布局
  3. AlertDialog 弹窗:清除缓存确认交互
  4. @Builder 回调模式:实现 UI 与逻辑分离
  5. 多状态变量管理:6 个 @State 协同工作

下篇将是本系列的收官之作——编译调试、打包发布与常见问题总结,涵盖清除缓存构建、HAP 打包、签名配置、模拟器/真机调试等实用内容。


http://www.rkmt.cn/news/1485141.html

相关文章:

  • AIGC】story_agent_loop架构初步探讨5
  • 51单片机+ADC0809测电压不准?可能是这些细节没做好(附校准方法与代码优化)
  • 2026 安徽亳州市彩钢瓦修缮 TOP4 权威推荐 + 避坑指南(全区域服务) - 本地便民网
  • 阜阳母婴除甲醛CMA甲醛检测治理公司深度测评:绿呼吸环保稳居榜首 - 一修哥咨询
  • 光学萌新看过来:用Light Tools做第一个简单照明仿真(附B站教程高效学习法)
  • 别只盯着环路!用MPS那个EMI视频里的思路,重新审视你的DCDC开关节点Layout
  • 2026年企业在线培训系统选型避坑:从需求分析到供应商评估的全流程拆解
  • 告别Hello World:用ESP32-IDF 4.3和Blink示例,5分钟点亮你的第一盏灯
  • S5.1注意力捕获——如何在信息过载中抓住用户眼球
  • 高级java每日一道面试题-2026年01月26日-实战篇[Docker]-如何实现容器的外部访问?端口映射的原理是什么?
  • 深入TI C2000内核:TMS320F280049的GPIO输入限定,如何为ePWM故障保护与通信外设保驾护航?
  • 人脸验证训练工具包:含T2T-ViT、BotNet、MobileFaceNet和ResNet四套可切换主干实现
  • 从Wireshark GUI到命令行:在无图形界面的CentOS 7服务器上,用tshark抓取并分析HTTP请求的完整流程
  • 别再死记硬背了!用PyTorch动手画一遍,彻底搞懂CNN和MLP到底啥关系
  • XUnity.AutoTranslator字体管理实战指南:如何解决Unity游戏多语言显示难题
  • 别再只用System.out.printf了!Java保留小数点的3种方法实战对比(含DecimalFormat避坑)
  • Qt 高级开发 028:以代码为笔,以界面为卷
  • 别再只会升级GCC了!遇到‘unrecognized command line option‘的三种排查思路与降级方案
  • NTC温度采集全套开发资源:单片机驱动+查表工具+上位机显示+硬件设计文件
  • 从需求到代码:手把手教你用PlantUML插件,在IDEA里自动生成时序图和类图
  • PSCAD仿真效率提升技巧:从元件布局、参数复用到底层波形导出全流程优化
  • 告别裸机:在STM32CubeIDE中为STM32H7集成SOEM 1.4.0的完整配置流程
  • HC-05蓝牙模块玩转无线PID调参:一个SerialPlot,让你的STM32小车/机械臂调试效率翻倍
  • 2026年6月7日当周国内AI编程新发展:从工具革新到生态重构
  • Chrome浏览器里点几下就能自动干活的插件,录个操作就能批量填表、抓数据、跳页面
  • 家庭网络拓扑图是怎么画出来的?聊聊IEEE 1905.1协议里的邻居发现与查询机制
  • 别再到处找了!9个遥感目标检测数据集(UCAS-AOD/DOTA/FAIR1M等)的下载、标注格式与实战加载指南
  • MATLAB环境下的Kriging代理模型构建工具包,集成LHS采样、多项式趋势项拟合与残差诊断功能
  • MATLAB处理GeoTIFF踩坑实录:从读取、显示到批量导出,一篇搞定所有地理信息问题
  • MyBatis-Plus BaseMapper 完全指南