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

HarmonyOS基础:鸿蒙系统组件导航Navigation

大家好!我是黑臂麒麟(起名原因:一个出生全右臂自带纹身的高质量程序员😏),也是一位6+(约2个半坤年)的前端;
学习如像练武功一样,理论和实践要相结合,学一门只是也是一样;
这里会用两周的时间把所学的常用ArkUI基础的常用组件输出在网;
如需深究可前往高级ArkTS系列课程;
望对学习鸿蒙小伙伴有所帮助;

介绍

Navigation组件:是路由导航根视图容器,一般作为Page页面(@Entry修饰符)的component作为根容器使用。在应用开发中起到了模块内和跨模块(对于在想要跳转到的共享包HAR/HSP页面里)的路由切换。

作为前端工程师,使用惯了vue-router/react-router,在使用Navigation有一定的学习成本,但使用起来后会发现其用法和vue-router/react-router的用法很像。

Navgiation

介绍

这里实现组件跳转要利用到Navigation组件、NavDestination组件、NavPathStack来实现跳转,这里简单介绍:

  • Navigation路由导航根容器,包括标题栏、菜单栏、工具栏等。
  • NavDestination是Navigation子页面的根容器用于承载子页面的一些特殊属性以及生命周期等,结构属性上跟Navigation一样
  • NavPathStack管理路由容器

跳转

在使用navigation编写路由页面,一般navigation作为路由的根页面。在配合NavPathStack管理子路由NavDestination页面

  private arr: number[] = [1, 2, 3];@Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()private TooTmpItem: NavigationMenuItem = {'value': "", 'icon': "resources/base/media/ic_01_on.svg", 'action': ()=> {}}@State menuItems: Array<NavigationMenuItem> = [{value: 'menuItem1',icon: 'resources/base/media/ic_01_on.svg', // 图标资源路径action: () => {}}]// 根据name,跳转相应的子路由页面@BuilderpageMap(name: string){if (name === 'NavDestinationTitle1'){pageOneTmp()}else if(name === 'NavDestinationTitle2'){pageTweTmp()}else if(name === 'NavDestinationTitle3'){pageThreeTmp()}}build() {Column(){Navigation(this.pageInfos){TextInput({ placeholder: 'search...' })...List({ space: 12 }){ForEach(this.arr, (item: number)=> {ListItem() {Text("NavRouter" + item)....onClick(() => {this.pageInfos.pushPath({name: "NavDestinationTitle" + item})})}}, (item: number) => item.toString())}...}.title("根路由页面") // navigation的标题.titleMode(NavigationTitleMode.Mini) // 标题模式 可选值:Mini、Normal、Full.mode(NavigationMode.Stack) // navigation页面显示模式:Stack(非折叠屏手机模式/正常显示屏幕)、Split(折叠屏手机/屏幕较大)、auto(自动判断).menus([this.TooTmpItem, this.TooTmpItem, this.TooTmpItem]) // 导航栏菜单按钮.navDestination(this.pageMap) // 路由容器.toolbarConfiguration([this.TooTmp, this.TooTmp, this.TooTmp]) // tabbar的配置}}@Component
export struct pageOneTmp {@Consume('pageInfos') pageInfos: NavPathStack;build() {NavDestination(){Column(){Text('NavDestinationContent1')}.width('100%').height('100%')}.title('子页面1').onBackPressed(() => {const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))return true})}
}@Component
export struct pageTweTmp {@Consume('pageInfos') pageInfos: NavPathStack;build() {NavDestination(){Column(){Text('NavDestinationContent2')}.width('100%').height('100%')}.title("子页面2").onBackPressed(() => {const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))return true})}
}

在Navigtion的属性navDestination,我们传入路由容器,根据name不同,渲染不同的页面。
请添加图片描述

子页面之间跳转

介绍子页面跳转之前会用到系统路由表,我们先介绍:

  1. 在跳转目标模块的配置文件module.json5添加路由表配置:
{"module" : {"routerMap": "$profile:route_map"}
}
  1. 添加完路由配置文件地址后,需要在工程resources/base/profile中创建route_map.json文件。添加如下配置信息:
{"routerMap": [{"name": "PageOne", // 跳转页面名称。"pageSourceFile": "src/main/ets/pages/PageOne.ets", // 跳转目标页在包内的路径,相对src目录的相对路径。"buildFunction": "PageOneBuilder", // 	跳转目标页的入口函数名称,必须以@Builder修饰。"data": { // 应用自定义字段。可以通过配置项读取接口getConfigInRouteMap获取。"description" : "this is PageOne"}}]
}
  1. 在跳转目标页面中,需要配置入口Builder函数,函数名称需要和route_map.json配置文件中的buildFunction保持一致,否则在编译时会报错。
// 跳转页面入口函数
@Builder
export function PageOneBuilder() {PageOne()
}@Component
struct PageOne {pathStack: NavPathStack = new NavPathStack()build() {NavDestination() {}.title('PageOne').onReady((context: NavDestinationContext) => {this.pathStack = context.pathStack})}
}
  1. 通过pushPathByName等路由接口进行页面跳转。(注意:此时Navigation中可以不用配置navDestination属性)。
@Entry
@Component
struct Index {
pageStack : NavPathStack = new NavPathStack();build() {Navigation(this.pageStack){}.onAppear(() => {this.pageStack.pushPathByName("PageOne", null, false);}).hideNavBar(true)
}
}

上面就是配置系统路由表,然后就能实现子页面之间的跳转,下面是完整代码。

// PageOne.ets
@Builder
export function PageOneBuilder(name: string, param: Object){PageOne()
}@Component
export struct PageOne {pageInfos: NavPathStack = new NavPathStack()build() {NavDestination(){Column() {Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }).onClick(() => {let tmp = new TmpClass();this.pageInfos.pushPathByName('pageTwo', tmp)})}.width('100%').height('100%')}.title('pageOne').onReady((context: NavDestinationContext) => {this.pageInfos = context.pathStack;})}
}
PageTwo.ets
@Builder
export function PageTwoBuilder(name: string, param: Object){PageTwo()
}
@Component
export struct PageTwo{pathStack: NavPathStack = new NavPathStack();build() {NavDestination() {Column(){Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule }).onClick(() => {console.info("1231231")this.pathStack.pushPathByName('pageOne', null)})}.width('100%').height('100%')}.title('pageTwo').onReady((context: NavDestinationContext) => {this.pathStack = context.pathStack;console.log('current page config info is' + JSON.stringify(context.getConfigInRouteMap()))})}
}

在我们配置了系统路由后,上面pageOne和pageTwo子页面我们定义NavPathStack路由栈,然后在onReady中获取到路由栈,然后在利用pushPtahName的方法进行页面跳转。

拦截

NavPathStack提供了setInterception方法,用于设置Navigation页面跳转拦截回调。该方法需要传入一个NavigationInterception对象,该对象包含三个回调函数:

this.pageInfos.setInterception({// 页面跳转前回调,允许操作栈,在当前跳转生效。willShow: (form: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar", operation: NavigationOperation, animated: boolean) => {if (typeof to === "string") {console.log("target page is navigation home page.");return}// 将跳转PageTwo的路由重定向PageOnelet target: NavDestinationContext = to as NavDestinationContext;if (target.pathInfo.name === "NavDestinationTitle2"){target.pathStack.pop();target.pathStack.pushPath({name: "NavDestinationTitle3"}, false)}},// 页面跳转后回调,在该回调中操作栈会在下一次跳转生效。didShow: (){},// Navigation单双栏显示状态发生变更时触发该回调。modeChange: () {}
})

参数获取

NavPathStack通过Get相关接口去获取页面的一些参数。

// 获取栈中所有页面name集合
this.pageStack.getAllPathName()
// 获取索引为1的页面参数
this.pageStack.getParamByIndex(1)
// 获取PageOne页面的参数
this.pageStack.getParamByName("PageOne")
// 获取PageOne页面的索引集合
this.pageStack.getIndexByName("PageOne")

页面返回

NavPathStack通过Pop相关接口去实现页面返回功能。

// 返回到上一页
this.pageStack.pop()
// 返回到上一个PageOne页面
this.pageStack.popToName("PageOne")
// 返回到索引为1的页面
this.pageStack.popToIndex(1)
// 返回到根首页(清除栈中所有页面)
this.pageStack.clear()

子页面

页面生命周期

子页面里比较重要的概念就是生命周期,其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期。其中,aboutToAppear和aboutToDisappear是自定义组件的生命周期(NavDestination外层包含的自定义组件),OnAppear和OnDisappear是组件的通用生命周期。剩下的六个生命周期为NavDestination独有。
生命周期时序如下图所示:
在这里插入图片描述

  • aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
  • onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。
  • onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行。
  • onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。
  • onShown:NavDestination组件布局显示之后执行,此时页面已完成布局。
  • onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。
  • onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。
  • onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。
  • onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。
  • aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。

结语

本篇文章的内容结束了。文章有不对或不完整的地方,望多指点;
望更多小伙伴们加入harmonyOS开发大家庭,壮大生态圈,让鸿蒙更好,让国产手机(物联网)系统更强大。
如对你学习有所帮助,希望可爱你动动小手,关注、点赞、收藏;

相关文章:

HarmonyOS基础:鸿蒙系统组件导航Navigation

大家好&#xff01;我是黑臂麒麟&#xff08;起名原因&#xff1a;一个出生全右臂自带纹身的高质量程序员&#x1f60f;&#xff09;&#xff0c;也是一位6&#xff08;约2个半坤年&#xff09;的前端&#xff1b; 学习如像练武功一样&#xff0c;理论和实践要相结合&#xff0…...

【K8S问题系列】Kubernetes 中 Pod 无法通过 Service 名称访问服务的 DNS 解析失败【已解决】

在 Kubernetes 中&#xff0c;Service 提供了一种稳定的方式&#xff0c;通过名称访问一组 Pod。当其他 Pod 无法通过 Service 名称访问服务&#xff0c;并且出现 DNS 解析失败时&#xff0c;通常会导致应用无法正常工作。本文将详细分析此问题的常见原因及其解决方案。 一、问…...

【下载工具】Internet Download Manager下载器介绍

Internet Download Manager&#xff08;简称IDM&#xff09;作为一款功能强大的下载管理软件&#xff0c;以其高效、稳定的特点受到了广大用户的青睐。本文将为您详细介绍IDM的功能特性以及具体的使用方法。 功能特性 加速下载&#xff1a;IDM通过多线程下载技术&#xff0c;…...

如何打开/关闭 GitLab 的版本检查功能?

本文分享如何打开/关闭 GitLab 的版本检查功能。 极狐GitLab 是 GitLab 的中国发行版【https://dl.gitlab.cn/ncecn6kb】&#xff0c;中文版本对中国用户更友好&#xff0c;文章以私有化部署的极狐GitLab 实例来演示版本检查功能的开启和关闭。强烈不建议关闭该功能&#xff0…...

java-web-day13-事务管理+spring aop

事务管理: 事务回滚 默认情况下,只有出现runtimeException(运行时异常)才回滚, 而如果出现其他异常,例如受检异常, 就不会回滚事务, 不过可以加上rollbackfor属性用于控制出现何种异常类型, 回滚事务 事务传播: 当一个事务方法被另一个事务方法调用时, 这个事务方法应该如何进行…...

MySQL详细安装教程

一、从MySQL官网安装 可以翻译成中文看起来就舒服多了 下载并打开安装包&#xff0c;能看到版本是8.0.36&#xff0c;双击运行或者右键选择打开&#xff0c;打开后是一个安装向导&#xff0c;这个安装向导会先帮我们安装一个 mysql-installer 的程序&#xff0c;再通过该程序安…...

文件系统和日志管理

一、文件系统 1.概述 文件系统&#xff1a;文件系统提供了一个接口&#xff0c;用户用来访问硬件设备&#xff08;硬盘&#xff09;。硬件设备上对文件的管理。文件存储在硬盘上&#xff0c;硬盘最小的存储单位是512字节&#xff08;扇区&#xff09;。文件在硬盘上的最小存储…...

【LeetCode】【算法】208. 实现 Trie (前缀树)

LeetCode 208. 实现 Trie (前缀树) 题目描述 Trie&#xff08;发音类似 “try”&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补全和拼写检查。 请你实现 Trie 类&…...

libaom 源码分析:帧间运动矢量预测

AV1 帧间运动矢量预测原理 运动矢量可以被相邻块预测,这些相邻块可以是空域相邻块,或位于参考帧中的时域相邻块;通过检查所有这些块,将确定一组运动矢量预测器,并用于编码运动矢量信息。空域运动矢量预测 两组空域相邻块可以被利用寻找空域 MV 预测器,第一组包括当前块的…...

Android TextView自动换行文本显示不全解决

某些情况下&#xff0c;TextView自动换行后&#xff0c;会出现每行结尾处显示不全的问题&#xff0c; 如图&#xff1a; 常见解决方案&#xff1a; 设置TextView的“ellipsize”属性为“end” 实测无效&#xff01;将TextView外部的Layout改为RelativeLayout 实测无效&…...

【LeetCode】【算法】394. 字符串解码

LeetCode 394. 字符串解码 题目描述 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字…...

最新整理:Selenium自动化测试面试题

1.selenium中如何判断元素是否存在? find_elements查找到的元素个数为0&#xff0c;find_element报错意味着元素不存在 2.如何判断元素是否出现? 判断元素是否出现&#xff0c;存在两种情况&#xff0c;一种是该元素压根就没有&#xff0c;自然不会出现;另外一种是有这样的…...

外包干了2年,快要废了。。。

先说一下自己的情况&#xff0c;普通本科&#xff0c;在外包干了2年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会让一…...

乐尚代驾十订单支付seata、rabbitmq异步消息、redisson延迟队列

账单信息 司机结束代驾之后&#xff0c;生成账单&#xff08;包含账单信息和分账信息&#xff09;司机发送账单给乘客乘客获取账单之后&#xff0c;进行支付 获取账单信息 order_bill表记录的账单信息&#xff0c;我们直接获取即可 Operation(summary "根据订单id获取…...

HCIP--3实验- 链路聚合,VLAN间通讯,Super VLAN,MSTP,VRRPip配置,静态路由,环回,缺省,空接口,NAT

学习目标&#xff1a; 链路聚合VLAN间通讯Super VLANMSTPVRRPip配置,静态路由,环回&#xff0c;缺省&#xff0c;空接口NAT 学习内容&#xff1a; 实验拓扑实验需求实验需求分析实验配置内容 &#xff08;每一个设备的每一步操作&#xff09;实验结果验证 1.实验拓扑 搭建 …...

Apple提出MM1.5:多模态大型语言模型微调的方法、分析和见解_mm1.5 模型下载

摘要 我们介绍了 MM1.5&#xff0c;一个新的多模态大型语言模型 (MLLM) 家族&#xff0c;旨在增强在富文本图像理解、视觉参照和定位以及多图像推理方面的能力。 在 MM1 架构的基础上&#xff0c;MM1.5 采用以数据为中心的模型训练方法&#xff0c;系统地探索了整个模型训练生…...

【毫米波雷达(三)】汽车控制器启动流程——BootLoader

汽车控制器启动流程——BootLoader 一、什么是Bootloader(BT)&#xff1f;二、FBL、PBL、SBL、ESS的区别三、MCU的 A/B分区的实现 一、什么是Bootloader(BT)&#xff1f; BT就是一段程序&#xff0c;一段引导程序。它包含了启动代码、中断、主程序等。 雷达启动需要由BT跳转到…...

AI 搜索来势汹汹,互联网将被颠覆还是进化?

最近&#xff0c;美国新闻集团起诉了知名 AI 搜索引擎 Perplexity AI。也许你会想&#xff0c;这不就是又一起“AI 惹官司”吗&#xff1f;其实&#xff0c;这次情况不太一样&#xff0c;甚至可能会改变我们未来上网的方式&#xff01; 争议的焦点是什么&#xff1f;是未来的 …...

《二分查找算法:在有序数组中搜索目标值》

目录 一、问题分析 二、二分查找算法原理 三、代码实现 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target&#xff0c;我们要写一个函数来搜索 nums 中的 target&#xff0c;如果目标值存在就返回它的下标&#xff0c;否则返回 -1。 …...

【万字总结】数据结构常考应用大题做法画法详解_树_哈希表_图_排序大总结

文章目录 1.树相关应用大题1.1 已知二叉树的中序序列和前序or中序&#xff0c;画出二叉树1.2 二叉树的遍历、树的遍历、森林的遍历总结1.3二叉树与森林之间的转换1.3.1 已知树的先序序列和中序序列&#xff0c;画出森林 1.4 二叉树的线索化1.5 二叉排序树1.5.1 二叉排序树的删除…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...