news 2026/8/31 11:04:30

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 跟随持握状态,让折叠屏/平板单手场景更友好。

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

JIT-Agent:动态生成智能体框架,让大模型自主规划工具与执行路径

最近在做 Agent 类项目时&#xff0c;我越来越明显感受到一个痛点&#xff1a;很多团队把智能体流程写成了“流水线死代码”。任务进来后&#xff0c;先调用哪个模型、使用哪些工具、按什么顺序执行&#xff0c;几乎全部在代码里固定死。一旦业务需求变化&#xff0c;就要改代码…

作者头像 李华
网站建设 2026/8/31 11:04:01

把JD贴进IDE两分钟开始面试?AI与IDE结合的真价值

那类把职位描述贴进 IDE、两分钟后开始模拟面试的工具概念&#xff0c;最近让不少人眼前一亮。它的吸引点不在于“快”&#xff0c;而在于它把面试准备这件事&#xff0c;从“刷资料、找面经、约真人模拟”压缩成了一条可重复执行的本地工作流。更进一步说&#xff0c;这类工具…

作者头像 李华
网站建设 2026/8/31 11:03:22

CEF 90.5.9 集成指南:版本解析、依赖文件与踩坑笔记

简介&#xff1a;本资源是面向C桌面应用开发者的CEF&#xff08;Chromium Embedded Framework&#xff09;二进制开发包&#xff0c;专为在Windows 64位平台嵌入现代Web渲染能力而设计&#xff0c;适用于需集成HTML5、CSS3、JavaScript及H.264视频播放能力的客户端项目。压缩包…

作者头像 李华
网站建设 2026/8/31 11:01:03

PrivaZer深度清理:擦除隐私痕迹并释放C盘空间

电脑用久了&#xff0c;有两个问题几乎每个人都会遇到&#xff1a;一是 C 盘悄悄变红&#xff0c;系统越来越慢&#xff1b;二是自己都记不清浏览器、聊天软件、办公软件在硬盘里留下了多少“个人痕迹”。很多时候我们以为删掉文件就安全了&#xff0c;其实在硬盘底层&#xff…

作者头像 李华
网站建设 2026/8/31 10:57:01

惠普 (HP) HyperX 暗影精灵MAX 16英寸游戏笔记本电脑 16-ah1xxx,16-ah1000原装出厂Windows11系统恢复镜像

惠普开箱状态原厂OEM预装Win11系统自带所有驱动、出厂主题壁纸、系统属性专属联机支持标志、系统属性专属LOGO标志、Office办公软件三件套、MyHP、惠小微、惠普管家HP Support Assistant、e管家、OMEN Command Center模式切换控制中心面板等预装软件程序适用型号&#xff1a;16…

作者头像 李华
网站建设 2026/8/31 10:56:46

FreeToken引擎实战:8GB显存跑35B大模型的部署与调优

这次我们来看一个正在被反复讨论的方向&#xff1a;FreeToken 引擎。它最抓眼球的说法是——让 8GB 显存的游戏本也能跑 35B 级别的开源大模型。这个卖点击中的是一大批本地模型玩家的真实痛点&#xff1a;显卡不是买不起 A100/H100 这类高端卡&#xff0c;而是手边只有一台 8G…

作者头像 李华