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

HarmonyOS 多设备短视频开发 : 17 — Navigation 路由与 NavPathStack

17 — Navigation 路由与 NavPathStack

一、引言

短视频应用中"视频页 → 评论区 / 个人主页"的跳转高频且要求无闪烁。HarmonyOS 的 Navigation 配合 NavPathStack 提供声明式路由能力。本项目在 default 产品层把 Navigation 作为导航根容器,通过 @Provider 下发全局导航栈,实现 Stack/Split 双模式切换与左右手持布局自适应。本文基于products/default/src/main/ets/view/Index.etsfeatures/multishortvideoindividual/src/main/ets/view/IndividualByRouter.ets与 route_map.json 展开。

二、Navigation 容器与全局导航栈

NavPathStack 在根组件创建,通过 @Provider 向子树共享,子组件用 @Consumer 拿到同一个栈对象:

@Entry @ComponentV2 struct Index { @Provider('pathStack') pathStack: NavPathStack = new NavPathStack(); @Provider('showSideComment') showSideComment: boolean = false; @Provider('showSideIndividual') showSideIndividual: boolean = false; build() { Navigation(this.pathStack) { MSVTabs({ data: this.data, ... }) } .navBarWidthRange([new WidthBreakpointType<number>(410, 410, 700, 700).getValue(this.windowInfo.widthBp), '100%']) .navBarWidth(new WidthBreakpointType<number>(410, 410, 700, 700).getValue(this.windowInfo.widthBp)) .hideBackButton(true) .hideTitleBar(true) .divider(null) .navBarPosition(this.holdingHandStatus === motion.HoldingHandStatus.RIGHT_HAND_HELD ? NavBarPosition.Start : NavBarPosition.End) .mode(this.showSideComment || this.showSideIndividual ? NavigationMode.Split : NavigationMode.Stack) .enableModeChangeAnimation(false) } }

要点:navBarWidth 随断点变化(XS/SM 用 410vp,MD/LG 用 700vp);navBarPosition 跟随持握状态;mode 由侧面板开关动态决定,enableModeChangeAnimation(false) 防闪跳。

三、NavDestination 与路由注册

路由目标用 NavDestination 声明(IndividualByRouter.ets):

@Builder export function IndividualByRouterBuilder() { IndividualByRouter() } @ComponentV2 export struct IndividualByRouter { @Consumer('pathStack') pathStack: NavPathStack = new NavPathStack(); @Consumer('showSideIndividual') showSideIndividual: boolean = false; aboutToAppear(): void { this.pathStack.disableAnimation(this.windowInfo.widthBp < WidthBreakpoint.WIDTH_MD ? false : true); } build() { NavDestination() { Individual() } .hideTitleBar(true) .hideBackButton(true) .onReady((context: NavDestinationContext) => { this.pathStack = context.pathStack; // 绑定页面级导航上下文 }) } }

路由映射在模块resources/base/profile/route_map.json注册,buildFunction 与导出的 @Builder 同名:

{ "routerMap": [ { "name": "IndividualByRouter", "pageSourceFile": "src/main/ets/view/IndividualByRouter.ets", "buildFunction": "IndividualByRouterBuilder" } ] }

default 产品层另注册了 SplitComment,各产品模块各自维护 route_map.json,路由互不干扰。

四、入栈、出栈与参数传递

视频页(AdaptiveVideo.ets)按断点选择跳转形态:

if (this.windowInfo.widthBp > WidthBreakpoint.WIDTH_SM) { this.showSideComment = true; // 大屏:分栏侧开 this.pathStack.pushPathByName('SplitComment', null); // 入栈,可携带参数 } else { this.showComment = true; // 小屏:半模态 } // 关闭侧面板 this.pathStack.pop(); this.showSideComment = false;

pushPathByName 的第二参可传任意对象,目标页在 aboutToAppear/onReady 中读取;onReady 回调返回 NavDestinationContext,其中的 pathStack 支持页面内返回与结果回传。

五、Stack/Split 双模式与多设备差异

NavigationMode.Stack 全屏压栈;Split 分栏时主内容区保持显示,NavDestination 作为右侧面板展开。四种产品差异如下:

产品容器navBarWidth分栏策略

defaultNavigation + MSVTabs410/700vp 按断点评论、个人主页 Split
pcSideBarContainer 内嵌 Navigation'66%'同上
tvNavigation + TvTabs880vp同上
wearableNavigation + 精简 Tabs全宽始终 Stack

TV 端(products/tv/src/main/ets/view/Index.ets)同样以 Navigation 为根容器,区别是页签用 TvTabs、navBarWidth 固定 880vp、无navBarPosition切换,其余 Stack/Split 逻辑与 default 一致。

六、点击主区关闭侧面板

侧面板打开时主内容区拦截点击,在 onGestureRecognizerJudgeBegin 中收起(REJECT 吞掉点击,防止误触播放):

.gesture(TapGesture()) .onGestureRecognizerJudgeBegin((event, current) => { if (current && (current.getType() === GestureControl.GestureType.TAP_GESTURE || current.getType() === GestureControl.GestureType.CLICK)) { if (this.showSideComment || this.showSideIndividual) { this.pathStack.pop(); this.showSideComment = false; this.showSideIndividual = false; return GestureJudgeResult.REJECT; } } return GestureJudgeResult.CONTINUE; })

配合hitTestBehavior(HitTestMode.Block),被拦截的点击不会透传给视频播放层。

七、总结与最佳实践

  • NavPathStack 全局唯一,用 @Provider/@Consumer 传递避免层层透传;页面内导航用 onReady 的页面级栈。
  • 路由统一注册到 route_map.json,buildFunction 与导出 @Builder 同名,保证映射可维护。
  • 模式切换由业务开关驱动,配合 enableModeChangeAnimation(false) 防止闪烁。
  • 大屏用 Split 分栏、小屏用半模态/Stack,断点驱动形态统一收敛在跳转处。
  • navBarPosition 跟随持握状态,让折叠屏/平板单手场景更友好。

http://www.cnnetsun.cn/news/4326826.html

相关文章:

  • JIT-Agent:动态生成智能体框架,让大模型自主规划工具与执行路径
  • 把JD贴进IDE两分钟开始面试?AI与IDE结合的真价值
  • CEF 90.5.9 集成指南:版本解析、依赖文件与踩坑笔记
  • PrivaZer深度清理:擦除隐私痕迹并释放C盘空间
  • 惠普 (HP) HyperX 暗影精灵MAX 16英寸游戏笔记本电脑 16-ah1xxx,16-ah1000原装出厂Windows11系统恢复镜像
  • FreeToken引擎实战:8GB显存跑35B大模型的部署与调优
  • springboot+vue 家谱管理系统源码 带小程序后台
  • claude-obsidian结合Obsidian Canvas:5步构建可视化知识地图的完整指南
  • 多Agent统一工作平台深度解析:从核心概念到Hermes Studio实战
  • cdai:基于意图解析的智能目录切换 CLI 工具设计实现
  • 零售业来了个新Agent:专查商品采销库存错配
  • freellmapi揭秘:从免费大模型API聚合到自建轻量网关实践
  • 专业肺结节CT数据集构建与分割模型调优实战
  • Python环境搭建与Jupyter实操:AI辅助调试到报告导出全流程指南
  • 毕业论文格式排版像做致谢?书霸AI帮你把感谢写得体体面面
  • Cherry Studio 教程:从零搭建支持多模型 LLM 的开源 AI 桌面助手(完整指南)
  • Positorium多模型数据库引擎:一体化部署与四类数据模型验证
  • 蓝绿部署与持续交付:用开源工具链实现低风险发布和快速回滚指南
  • 从Prompt到Skill:构建AI-Native组织的可复用技能体系
  • 开源机器人Microduck销售额破百万,开源硬件商业化闭环如何跑通?
  • 多智能体强化学习中的Simulator Collapse:为何一个冻结模拟器不够?
  • 程序员如何用GitHub开源项目打造可持续英语学习闭环?
  • VMware Workstation 虚拟机从入门到排错:安装配置、快照克隆与常见问题
  • POD电商如何用AI批量生成商品图?图案提取到自动上样全流程解析
  • AI Website Cloner Template伦理指南:网站克隆如何不踩目标站方的版权红线
  • 从Webpack到Vite+tsup+Rolldown:构建工具组合拳的实践与思考
  • 安检X光目标检测数据集:10类物品YOLOV5训练实践
  • graphify 中文支持完整指南:jieba 分词让知识图谱中文查询更精准
  • GPU Driven Rendering:Compute Shader实现细节全解析
  • TVA具身智能架构:面向开放场景的开放词汇目标检测