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

【OpenHarmony/HarmonyOs 】数学视界实战:悬浮导航栏、沉浸光感与全新交互体验

【OpenHarmony/HarmonyOs 】数学视界实战:悬浮导航栏、沉浸光感与全新交互体验

项目类型:OpenHarmony / HarmonyOS ArkTS 数学学习应用
项目名称:数学视界
关键词:ArkUI、Tabs、沉浸式视觉、深色模式、底部导航、点击动效、响应式布局 ✨

一、为什么要做“轻沉浸”的数学学习体验?

数学类应用很容易做成“工具集合”:计算器、公式表、单位换算、题库练习各自独立,页面之间缺少情绪连接。我的这个项目希望让用户打开应用时,不只是看到一堆功能按钮,而是进入一个有节奏、有反馈、有学习目标的空间。

所以在 UI 设计上,我重点做了三件事:

  • 🌈 用暖色光感做首页视觉入口,让学习氛围更轻松;
  • 🧭 用底部导航承载高频页面:首页、挑战、成就、收藏、我的;
  • 👆 给按钮、卡片、弹窗都加上统一点击反馈,让每一次操作都有回应。

最终效果上,应用并不是简单堆 ArkUI 组件,而是围绕“今日目标 -> 功能探索 -> 学习数据 -> 成就反馈”形成一个完整体验闭环。

二、项目首页结构:Tabs 承载五大核心场景

项目的主入口在entry/src/main/ets/pages/Index.ets,首页没有使用多个独立 Ability,而是通过Tabs把几个主要场景组织到同一个主页面里。

核心结构如下:

Tabs({barPosition: BarPosition.End,controller:this.tabController}){TabContent(){ this.buildHomePage()} .tabBar(this.buildBottomTab(0, '🏠', '首页'))TabContent(){ this.buildChallengeTab()} .tabBar(this.buildBottomTab(1, '🎯', '挑战'))TabContent(){ this.buildAchievementTab()} .tabBar(this.buildBottomTab(2, '🏆', '成就'))TabContent(){ this.buildFavoritesTab()} .tabBar(this.buildBottomTab(3, '💖', '收藏'))TabContent(){MyPage()} .tabBar(this.buildBottomTab(4, '👤', '我的')) } .barHeight(56).barBackgroundColor(this.getColor('#FFFDF7', '#1C1C1E')) .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])

这里有几个细节很关键:

  1. barPosition: BarPosition.End:把导航固定在底部,更符合移动端单手操作习惯。
  2. TabsController:为后续主动切换 Tab 留出扩展空间。
  3. expandSafeArea:处理底部安全区域,让导航不会被系统手势区域遮挡。
  4. 自定义tabBar:不用系统默认样式,而是自己绘制图标、文字、角标。

三、底部导航栏:不只是切换页面,还要承担状态表达

数学视界的底部导航有一个小设计:收藏 Tab 会显示收藏数量角标。这样用户不用进入收藏页,也能知道自己积累了多少内容。

@Builder buildBottomTab(index:number,icon:string,title:string){Column({space: 2 }){Stack({alignContent: Alignment.Center }){Text(icon).fontSize(24)if(index===3&&AppState.favorites.length >0) {Text(AppState.favorites.length> 99 ? '99+' : AppState.favorites.length.toString()) .fontSize(9).fontColor('#FFFFFF').backgroundColor(this.isDarkMode? '#FF7A8A' : '#FF6B9D').borderRadius(10).padding({ left:3, right:3, top:1, bottom:1}) .offset({ x:14, y: -10}) } }Text(title).fontSize(11).fontWeight(this.currentIndex===index? FontWeight.Bold : FontWeight.Normal).fontColor(this.currentIndex===index?getThemeColors().primary : this.getColor('#AAAAAA', '#666666')) .textAlign(TextAlign.Center)} }

这个写法的好处是:

  • 当前选中态通过字重和颜色表达,用户不会迷路;
  • 收藏数量直接关联AppState.favorites.length,数据变化会反映到 UI;
  • 深色模式下角标颜色也会调整,不会出现浅色主题好看、深色主题刺眼的问题。

四、沉浸光感:从首页头图到进度卡片

首页最醒目的区域是顶部标题和今日进度。它们都使用了比较明亮的暖粉色,形成统一的品牌感。

Text('🌟 数学视界').fontSize(this.isLargeScreen? 26 : 22).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')Text('探索数学的奇妙世界').fontSize(this.isLargeScreen? 14 : 12).fontColor('rgba(255,255,255,0.85)')

进度卡片则把“今日目标”直接视觉化:

Column() .width(Math.min(AppState.studyData.todayCount / AppState.studyData.dailyGoal *100,100) +'%') .height('100%') .backgroundColor('#FFFFFF') .borderRadius(10)

这里我没有把学习数据藏在“我的”页面里,而是放在首页首屏。原因很简单:学习类产品最重要的是持续激励,用户一打开就应该知道“今天还差多少”。

页面文案也做了轻量反馈:

Text( AppState.studyData.todayCount >= AppState.studyData.dailyGoal ?'🎉 太棒了!今日目标达成!':'💪 再完成 '+ Math.max(AppState.studyData.dailyGoal - AppState.studyData.todayCount,0) +' 次即可达成今日目标!')

这类微文案虽然代码很短,但对学习应用的体验很重要。它让进度条不只是一个数字,而是一个“被鼓励”的瞬间。

五、统一点击动效:让交互有手感

项目中很多按钮、卡片、弹窗关闭按钮都用了同一套点击反馈。核心思路是:点击时记录当前元素的id,短时间内让该元素缩小和降低透明度。

pulseAnim(id:string):void{this.animId= idif(this.animTimer>=0)clearTimeout(this.animTimer)this.animTimer=setTimeout(():void=>{this.animId=''},200)asnumber}animScale(id:string):number{returnthis.animId=== id ?AnimScale.PRESSED:1}animAlpha(id:string):number{returnthis.animId=== id ?AnimAlpha.PRESSED:1}

在功能卡片上使用:

.scale({ x: this.animScale('mod_'+ title), y: this.animScale('mod_'+ title) }).opacity(this.animAlpha('mod_'+ title)).animation({ duration: AnimDuration.NORMAL, curve: Curve.EaseOut}).onClick(() => { this.pulseAnim('mod_'+ title) action() })

体验上会变成这样:

  • 用户点卡片时,卡片轻微下压;
  • 点击反馈在 200ms 左右结束;
  • 动画不会抢戏,但会让页面更“活”。

我把这类动效抽到了AnimationUtils.ets,统一维护时长、缩放值和透明度:

export const AnimDuration={FAST:100,NORMAL:150,SLOW:300,VERY_SLOW:500,}export const AnimScale={PRESSED:0.93,SMALL:0.95,LARGE:1.05,}export const AnimAlpha={PRESSED:0.82,DISABLED:0.5,}

这样后续新增页面时,不需要每个页面都重新想一套动画参数,整套应用的手感会保持一致。

六、深色模式:不是简单反色,而是主题系统

项目中有一个统一的ThemeManager,用于管理浅色主题、深色主题、图标背景映射和响应式工具。

exportconstLightTheme: ThemeColors = { primary:'#FF7A8A', background:'#FFF8F0', surface:'#FFFFFF', textPrimary:'#2C3E50', tabBarBackground:'#FFFDF7', }exportconstDarkTheme: ThemeColors = { primary:'#FF7A8A', background:'#000000', surface:'#1C1C1E', textPrimary:'#F2F2F7', tabBarBackground:'#1C1C1E', }

深色模式最容易踩坑的地方是图标背景。浅色模式下很多柔和色块很舒服,但放到黑色背景上会显得发灰或发脏。因此项目里单独维护了图标背景映射:

exportfunctiongetIconBgColor(lightColor:string,isDark:boolean):string{if(!isDark) return lightColor const mapping = IconBgColorMap[lightColor]if(mapping) return mapping.dark return adjustColorForDark(lightColor)}

这样首页、我的页面、挑战页都可以复用:

getIconBg(bgColor:string):string{ return getIconBgColor(bgColor,this.isDarkMode)}

七、状态栏同步:让系统区域也融入视觉

EntryAbility.ets中,应用会读取系统配置并更新主题状态,同时设置状态栏颜色。

onConfigurationUpdate(newConfig: Configuration): void { ThemeManager.getInstance().applyColorMode(newConfig.colorMode)this.applyStatusBar() }privateapplyStatusBar(): void {if(this.mainWindow ===null)returnconstisDark = ThemeManager.getInstance().isDark()this.mainWindow.setWindowSystemBarProperties({ statusBarColor: isDark ?'#1C1C1E':'#FF9A8B', statusBarContentColor:'#FFFFFF'}) }

这一步会让应用不只是内容区变色,连状态栏也与页面主色协调起来。对于“沉浸光感”来说,这种细节非常重要。

八、响应式适配:手机和平板都要能用

项目在ThemeManager.ets中封装了ResponsiveUtils

exportclassResponsiveUtils{privatestaticreadonlyBASE_WIDTH=375staticgetScreenWidth(): number {returngetScreenSize().width }staticisLargeScreen():boolean{returngetScreenSize().width >=600}staticgetGridColumns(): number {returnResponsiveUtils.isLargeScreen() ?4:2} }

首页里根据屏幕宽度调整字号、间距和内容宽度:

getisLargeScreen() {returnthis.screenWidth >=600}

这让应用在手机上保持紧凑,在平板上则不会显得内容过小。

九、实现总结

这篇文章对应的主题是“悬浮导航栏、沉浸光感、全新视觉与交互体验”。在数学视界项目里,我主要通过以下方式实现:

  • 🧭 使用Tabs + 自定义 tabBar构建底部导航;
  • 🌈 使用暖色头部、进度卡片和轻渐变营造学习氛围;
  • 👆 抽象AnimDuration / AnimScale / AnimAlpha,统一点击动效;
  • 🌙 使用ThemeManager管理深色模式和图标背景映射;
  • 📱 使用ResponsiveUtils处理手机和平板适配;
  • 🧩 把首页、挑战、成就、收藏、我的组成完整学习闭环。

如果你也在做 OpenHarmony / HarmonyOS 应用,不建议一开始就追求复杂动画。先把导航、主题、点击反馈、状态栏、安全区域这些基础体验做好,应用的完成度会立刻提升一大截。🚀

http://www.gsyq.cn/news/1637160.html

相关文章:

  • 基于51单片机的气象站环境检测系统 风速风向温湿度 气象监测仪24(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 微服务合同测试:创业团队也别只靠联调
  • 2026美妆行业会员管理系统怎么选?跨店互通、复购提升、成本对比
  • 2026年一键生成论文工具实测:5款AI神器闭眼选不翻车
  • VRoid Studio中文汉化完整攻略:5步摆脱英文界面困扰
  • 5分钟快速上手:Mi-Create可视化小米手表表盘设计终极指南
  • YOLO26 全网独家改进创新:ECCV2026 S2-FracMix 颈部网络,引入形状-尺度分形混合 Neck,独家创新!
  • Three.js 粒子星空教程
  • 数学公式编辑革命:为什么MathLive成为现代Web开发者的首选方案?
  • 分享一个好用的免费远程工具APP
  • 机器人高算力平台上车前,整机评审要检查哪些工程约束?
  • 终极指南:如何用ViGEmBus驱动在Windows上轻松创建虚拟游戏控制器
  • Python 自动化任务:Cron 之外还要有状态机
  • Windows Cleaner:告别C盘爆红,让你的电脑重获新生!
  • 第44篇:网络抖动、接口偶发卡顿?抓包看懂TCP丢包重传真相
  • 前端工程化-01:前端工程化技术栈
  • 蓝速科技 RISC-V 鸿蒙信创终端全场景落地方案
  • Chrome DevTools 3步定位 Blob 视频源:从 Network 面板到 m3u8 链接实战
  • 显卡驱动彻底清理指南:3分钟掌握DDU专业工具
  • 5步构建企业级数据治理平台:OpenMetadata深度实践指南
  • 手机内存不足怎么清理不删文件?免费方案+靠谱工具推荐|避坑指南
  • ng系列.
  • VRRTest:3步检测你的显示器可变刷新率是否真正工作
  • SQL注入从原理到实战:手工注入、绕过技巧与安全防御详解
  • AI写教材必备攻略!掌握这些技巧,低查重生成高质量教材不是梦
  • 豆包、千问下线智能体:不是 Agent 凉了,是野蛮生长期结束了
  • 镜像视界纯视觉无感定位视频孪生底层技术全解
  • STM32F405RG驱动WS2812 LED的嵌入式开发实践
  • 配置文件的工程化管理:从环境变量到结构化配置的演化路径
  • 探索 Aqua,Hyperliquid 如何打通衍生品流动性向零售渗透的最终圣杯