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

OpenHarmony 英语学习 App 实战:悬浮导航栏、沉浸光感与全新交互体验

OpenHarmony 英语学习 App 实战:悬浮导航栏、沉浸光感与全新交互体验

摘要

在做英语学习类 App 时,功能完整只是第一步。真正影响用户是否愿意每天打开应用的,是进入页面后的第一感受:界面是否清爽?学习路径是否明确?点击后有没有反馈?学习进度是否一眼可见?📚✨

本文以我的 OpenHarmony/HarmonyOS 英语学习项目「英语视界 YingYu」为例,分享如何使用 ArkTS + ArkUI 打造一套更适合学习场景的首页体验:悬浮导航栏、沉浸光感背景、卡片式学习面板、轻量动效反馈以及多入口学习动线

项目本身包含词汇学习、听力训练、每日一句、语法专题、短语学习、复习中心、成就系统等功能。为了让这些模块不显得零散,我在新版首页MainTabsV2.ets中重构了整体交互,让首页从“页面入口集合”升级成“学习驾驶舱”。

一、项目背景:为什么学习 App 需要更好的视觉体验?

很多工具类学习 App 容易陷入一个问题:功能很多,但用户不知道先点哪里。尤其是中小学生用户,打开 App 后如果看到的是密集列表、复杂入口和冷冰冰的数据,很容易产生压力。

所以我在「英语视界」里希望做到三点:

  1. 降低学习压力:用柔和色彩、圆角卡片、低对比背景营造轻松氛围。
  2. 提高任务感知:让今日目标、已学词汇、连续学习天数等信息直接出现在首页。
  3. 增强操作反馈:Tab 切换、图标选中、卡片点击都要有轻量动画和状态变化。

新版首页不是简单地“换皮肤”,而是围绕学习场景重新组织信息层级。

二、启动新版首页:MainTabsV2 作为主入口

EntryAbility.ets中,应用启动后优先加载新版首页MainTabsV2,如果加载失败再回退旧版MainTabs

onWindowStageCreate(windowStage: window.WindowStage):void{ windowStage.loadContent('pages/MainTabsV2',(err)=>{if(err.code) { console.error('Failed to load MainTabsV2: '+JSON.stringify(err)) windowStage.loadContent('pages/MainTabs',(fallbackErr)=>{if(fallbackErr.code) { console.error('Fallback load failed: '+JSON.stringify(fallbackErr)) } })return} console.info('Succeeded in loading MainTabsV2.') }) }

这样设计有两个好处:

  • 新版首页可以承载更完整的视觉和交互体验;
  • 旧版页面仍然作为兜底,降低页面重构带来的风险。

对实际项目来说,UI 大改时保留 fallback 是一个很实用的策略。尤其是移动端入口页,一旦入口页异常,整个 App 体验都会受影响。

三、用 Stack 构建沉浸式页面层级

MainTabsV2的整体结构采用Stack分层:

  • 最底层:页面背景色;
  • 第二层:低透明度光斑;
  • 中间层:Tabs 页面内容;
  • 顶层:自定义悬浮导航栏。

核心代码如下:

build(){ Stack({ alignContent: Alignment.TopStart}) { Column().width('100%').height('100%').backgroundColor($r('app.color.neo_background')) Column() { Column().backgroundColor($r('app.color.neo_primary')).opacity(0.06).borderRadius(200).width(280).height(280).position({ x:'60%', y:'-8%'}) Column().backgroundColor($r('app.color.neo_secondary')).opacity(0.05).borderRadius(180).width(220).height(220).position({ x:'-5%', y:'50%'}) }.width('100%').height('100%') this.MainTabsContent() this.BottomNavBar() }.width('100%').height('100%') }

这里的“沉浸光感”不是用一张背景图硬铺,而是通过低透明度色块、圆形边界和错落位置来营造空间层次。学习类 App 不适合过度炫酷,因此透明度控制得比较克制,整体观感更柔和。

四、隐藏默认 TabBar,自绘悬浮导航

ArkUI 的Tabs组件本身可以快速实现多页切换,但默认底部栏不一定满足个性化设计。这里我保留了TabsController的页面管理能力,同时隐藏默认 tabBar,再单独绘制一个悬浮导航。

Tabs({ index:this.currentIndex, controller:this.tabsController }) { TabContent() {this.HomeTab() } .tabBar(this.tabBarBuilder('首页', $r('sys.symbol.house_fill'),0)) TabContent() {this.StudyTab() } .tabBar(this.tabBarBuilder('学习', $r('sys.symbol.book'),1)) TabContent() {this.PracticeTab() } .tabBar(this.tabBarBuilder('练习', $r('sys.symbol.square_grid_2x2'),2)) TabContent() {this.ProfileTab() } .tabBar(this.tabBarBuilder('我的', $r('sys.symbol.person_crop_circle_fill'),3)) } .barPosition(BarPosition.End) .barHeight(this.isTabletDevice ?88:80) .barBackgroundColor(Color.Transparent)

默认 tabBar 通过 builder 隐藏:

@BuildertabBarBuilder(label: string,icon: Resource,index: number) { Column() { SymbolGlyph(icon).fontSize(24) }.width(48).height(32).visibility(Visibility.Hidden) }

这样做的思路是:页面切换仍然交给系统 Tabs,视觉展示交给自定义导航栏。逻辑和视觉分离后,后续要换导航样式会更容易。

五、悬浮导航栏的实现细节

底部导航栏使用Column + Row自绘,宽度设置为88%,左右留出空间,让它真正“浮”在页面上。

@BuilderBottomNavBar(){ Column() { Row() { this.NavItem('首页',$r('sys.symbol.house_fill'),0) this.NavItem('学习',$r('sys.symbol.book'),1) this.NavItem('练习',$r('sys.symbol.square_grid_2x2'),2) this.NavItem('我的',$r('sys.symbol.person_crop_circle_fill'),3) }.width('100%').height('100%').justifyContent(FlexAlign.SpaceAround).alignItems(VerticalAlign.Center) }.width('88%').height(72).borderRadius(36).backgroundColor('rgba(255, 255, 255, 0.95)').shadow({ radius:24,color:'rgba(0, 0, 0, 0.08)', offsetX:0, offsetY:8}).position({ x:'6%', y:'95.5%'}) }

这里有几个小技巧:

  • width('88%'):比满宽更有空气感;
  • borderRadius(36):高度 72,对应胶囊形态;
  • rgba(255, 255, 255, 0.95):接近白色但保留一点透气感;
  • shadow radius 24:让导航从背景中“抬起来”;
  • position({ x: '6%', y: '95.5%' }):固定在底部视觉区域。

这种做法适合首页、工具页、学习面板等高频页面。用户视觉上会感觉导航栏是页面的一部分,而不是一个生硬的系统控件。

六、导航项状态:颜色、背景、缩放三层反馈

每个导航项由图标和文字组成,选中时改变颜色、字重、背景色。

@BuilderNavItem(label:string,icon: Resource,index:number){Column(){SymbolGlyph(icon).fontSize(this.iconScale[index]*24).fontColor([this.currentIndex===index? '#FF6B35' : '#8A94A7']).fontWeight(this.currentIndex===index? FontWeight.Bold : FontWeight.Normal)Text(label).fontSize(11).fontWeight(this.currentIndex===index? FontWeight.Medium : FontWeight.Normal).fontColor(this.currentIndex===index? '#FF6B35' : '#8A94A7').margin({ top:2}) } .padding({ left:20, right:20, top:8, bottom:8}) .borderRadius(20).backgroundColor(this.currentIndex===index? 'rgba(100, 210, 177, 0.15)' : Color.Transparent) .onClick(()=> { this.tabsController.changeIndex(index)}) }

这里没有用复杂动画,但反馈层次足够清晰:

  • 选中图标:橙色;
  • 未选中图标:灰蓝色;
  • 选中背景:淡薄荷色;
  • 点击动作:切换 Tab;
  • 字重变化:强化当前页面。

七、Tab 切换动效:轻微放大再回落

导航点击后,图标会先放大到1.15,再回落到1。这个动效非常轻,但用户能明显感受到“点击成功”。

.onChange((index: number)=>{ animateTo({ duration:200, curve: Curve.EaseOut },()=>{ this.iconScale[this.prevIndex] =1this.iconScale[index] =1.15})setTimeout(()=>{ animateTo({ duration:150, curve: Curve.EaseOut },()=>{ this.iconScale[index] =1}) },180) this.prevIndex = index this.currentIndex = index })

学习类产品的动效应该“轻”,不能过度打扰。这里的动画只是提示状态变化,不会抢走学习内容的注意力。

八、学习面板:把核心数据放进第一屏

首页不是展示型 Banner,而是直接呈现学习状态,例如:

  • 当前年级;
  • 已学词汇数量;
  • 词库总数;
  • 今日学习目标;
  • 连续学习天数;
  • 快捷入口。

部分代码如下:

Row(){ Text(this.totalWords.toString()).fontSize(32).fontWeight(FontWeight.Bold).fontColor('#FF6B35') Text('/'+ vocabularyData.length).fontSize(14).fontColor('#999999').margin({bottom:4}) }Text('已学词汇').fontSize(12).fontColor('#666666')

我认为学习类 App 首页应该回答三个问题:

  1. 今天我要做什么?🎯
  2. 我现在学到哪里了?📈
  3. 下一步从哪里进入?🚀

所以首页的设计不应该只是“好看”,而是要服务学习路径。

九、响应式适配:手机和平板共用一套逻辑

项目中会判断当前设备是否为平板,并调整导航高度和标题字号:

aboutToAppear(): void {this.isTabletDevice = isTablet()this.isPhone = !this.isTabletDevice && deviceInfo.deviceType ==='phone'this.loadData() }

例如:

.barHeight(this.isTabletDevice? 88 : 80)

学习 App 很适合手机和平板双端使用。手机适合碎片化背单词,平板适合做语法、听力和复习。因此从首页阶段就预留设备适配,会让后续扩展更顺畅。

十、实现过程中的几个经验

1. 不要把所有装饰都放到前景

沉浸光感要服务内容,不能压过内容。背景装饰建议低透明度、低饱和、少动效。

2. 自定义导航不要放弃系统控制器

完全手写页面切换会增加状态管理复杂度。使用TabsController管理切换,再自绘导航,是比较稳的做法。

3. 动效要短

学习类 App 不适合很长的转场动画。图标缩放、卡片阴影、透明度变化这类轻反馈更自然。

4. 首页一定要有任务感

用户打开学习 App 不是来欣赏 UI 的,而是来完成学习任务的。视觉体验越好,越要把“开始学习”这件事变简单。

十一、小结

这次首页改造的重点可以总结为:

  • 使用Stack构建沉浸式视觉层级;
  • 使用低透明度光斑打造柔和背景;
  • 保留TabsController,自绘悬浮导航栏;
  • 通过颜色、背景、缩放表达选中状态;
  • 使用animateTo()增强点击反馈;
  • 首页直接展示学习目标和学习进度;
  • 为手机和平板预留响应式适配。

OpenHarmony/ArkUI 的声明式开发方式很适合做这种体验升级。一个好的学习 App,不只是把知识塞进去,更重要的是让用户愿意每天回来。🌱

http://www.jsqmd.com/news/1106045/

相关文章:

  • 【信息科学与工程学】【制造工程】第八十三篇 计算机系统集成制造01
  • 字节豆包AI编程助手扩展:深度解析其代码能力边界与实战表现
  • EM3080-W与PIC32MZ的嵌入式条形码解码系统设计
  • 什么是数字工厂全要素智造中枢与适用于哪种企业
  • LeetCode 23.合并K个升序链表
  • Android 7系统日志(四)日志写入接口—Java层与Native层
  • Codex 插件生态全景:从官方工具到社区神器
  • 工程化应用基础设施:可观测性要覆盖 提示词、检索和执行
  • HBM Predictor安装与配置教程:简单5步搭建预测环境
  • Visa、Stripe等140余家机构联合推出Open USD稳定币,剑指Tether
  • 第92题 IGBT模块封装用高可靠铝线键合与铜线键合
  • 2026手机证件照制作工具实操指南:免费无水印软件梳理与收费坑避雷
  • Windows安卓应用安装神器:APK Installer完全指南 - 3分钟掌握跨平台应用管理
  • 年入100亿压缩机龙头IPO!1.66亿诉讼案未决,应收账款质量恶化
  • 让大模型跑在小芯片上:工程挑战比口号更硬
  • 番茄小说下载器终极指南:三分钟打造个人离线图书馆的完整教程
  • 记录:2026.7.1
  • 告别复杂配置!Claude Code完整安装指南,小白也能10分钟上手(Linux/WSL2)
  • 从 Hermes Agent 到 Harness 工程:AI Agent 落地,靠的不只是大模型
  • 单帧像素推演三维空间,SpaceOS联动Pixel2Geo打通单画面实景重建全链路
  • YOLOv11 改进 - C2PSA C2PSA融合EDFFN高效判别频域前馈网络(CVPR 2025):频域筛选机制增强细节感知,优化复杂场景目标检测
  • novel-downloader:三步搞定网络小说永久保存的终极指南
  • ChatGPT Plus / Pro 付款后没看到结果,先查这几步
  • 原生Signals正式落地、管道操作符终结“嵌套地狱”、WebNN调用NPU算力——4个让前端代码“减重”50%的ES2026特性
  • 孩子确诊自闭症/多动症后该找谁?一份给迷茫家长的专业参考指南
  • 软件设计周期
  • 卡梅德生物科普:CD70(TNFSF7)的免疫共刺激机制与研究应用
  • 基于SpringBoot+Vue的日常办公用品直售推荐系统管理系统设计与实现【Java+MySQL+MyBatis完整源码】
  • 类成员变量的初始化 _
  • M4Markets的长期使用感受顺不顺手?