【HarmonyOS】ArkUI - 页面路由

news2024/11/16 22:44:03

一、概念

页面路由是指在应用程序中实现不同页面之间的跳转和数据传递。

案例:第一次使用某个购物应用,打开时肯定会是一个登录页,在登录成功以后,会跳转到首页,然后可能会去搜索,就会进入到搜索列表页,接着呢如果搜索到某一个感兴趣的商品A,点击,就会进入到商品A的详情页,到现在为止已经访问了好多不同的页面,并且在它们之间完成了跳转,那我之前访问过的页面都去哪里了?是不是全部被销毁了?其实并没有,我们在页面跳转之间访问过的所有页面,都会被 HarmonyOS 保存到页面栈的空间当中。页面栈顾名思义就是保存页面的栈结构空间,栈结构是先进后出,所以呢,我们最早访问的登录页就被压到了栈的最底层,而当前正在访问的商品A的详情页就在栈顶。也就是说,谁在栈顶,当前显示的就是谁的页面。那么 HarmonyOS 为啥要把这些访问过的页面保存起来,而不是直接销毁掉呢?放在这里不占用内存吗?这其实是我们的页面功能需要去用到这些历史页面。一般商品详情页都会有返回按钮,当点击返回按钮,应该返回到之前访问过的搜索列表页,有了页面栈,想要实现这个功能就非常简单了。只需要在点击返回时,把栈顶的这个页面移除,这样一来,紧挨着栈顶的搜索列表页就成为了新的栈顶页面,现在显示的就是搜索列表页,从而也就实现了返回的效果。如果现在想做页面跳转,过程就相反,比如在搜索列表页点击商品B,只需要把商品B的详情页创建出来,然后压入栈里,现在栈顶就是商品B的详情页,从而实现了跳转效果。简单来讲,如果想实现创建页面,就压入栈;如果想实现返回,就把栈顶页面弹出栈,即可。

  1. 页面栈的最大容量:

    页面栈的最大容量上限为 32 个页面。就是说如果我们不断的去访问新的页面,往栈里压入页面,可能就会达到上限,这时候再想访问这个页面,再想往里面去压栈,就会报错,这时候就不得不去调用 router.clear() 方法去清空页面栈,就会把历史页面干掉,释放内存。但是,一旦把历史页面干掉,再想返回前一个页面就访问不了了。所以 router.clear() 要慎重使用。我们在开发的过程中一定要想办法控制页面栈里的页面数量,不要让它达到上限,而不是说等达到上限去清空。

  2. 怎么去控制页面栈里的页面数量呢?就要使用页面栈不同的跳转行为模式。Router 有两种页面跳转模式:

    • router.pushUrl():目标页不会替换当前页,而是压入页面栈。比如当前在商品A的详情页,如果点击商品B的图片,就需要压入栈,就需要创建一个商品B的页面,把商品B的详情页压入栈顶,这时候,原有的商品A的详情页不会被移除,而是压到栈的内部,成为一个历史页面,因此点返回按钮,用 router.back() 就会返回到历史页面商品A的详情页。但是,这种实现方式会导致栈里的页面会越来越多。

    • router.replaceUrl():目标页替换当前页,当前页会被销毁并释放资源。也就是说从商品A的详情页跳转到商品B的详情页,这时候商品A的详情页就变成了历史页,会直接被销毁,而不是在栈内保存。这样一来,内存就节省出来,但是如果想从商品B的详情页返回到商品A的详情页,就返回不了了。

  3. 何时使用 router.pushUrl(),何时又使用 router.replaceUrl() 呢?

    举个例子,比如说,我们的登录页,只有在第一次打开的时候才需要,只要不退出,就不用再登录。所以登录页基本上就访问一次,而且也不需要返回,登录页保存在历史页面栈里没有任何意义,所以在登录成功以后,跳转到首页时,就可以使用 router.replaceUrl() 把登录页销毁;如果我们从首页跳转到搜索列表页,如果这时候点返回,返回到首页,所以我们的首页应该在页面栈里保存,作为一个历史页面,就要用 router.pushUrl()

  4. 如果商品A的详情页和商品B的详情页来回切换,如果用到 router.pushUrl(),会导致页面栈的容量一会儿就满了,就要用到页面实例模式,Router 有两种页面实例模式:

    • Standard:标准实例模式,每次跳转都会新建一个目标页并压入栈顶。默认就是这种模式。

    • Single:单实例模式,顾名思义,每一个页面只会存在一份,如果目标页已经在栈中,则离栈顶最近的同Url页面会被移动到栈顶并重新加载。

结合合适的跳转模式(router.pushUrl()router.replaceUrl())和实例模式(StandardSingle),就能够控制页面栈里的页面数量,避免达到上限。

二、Router API 用法

  1. 首先要导入 HarmonyOS 提供的 Router 模块:

    import router from '@ohos.router';
    
  2. 然后利用 router 实现跳转、返回等操作:

    router.pushUrl(
      {
        url: 'pages/PageA',
        params: { id: 1 }
      },
      router.RouterMode.Single,
      err => {
        if (err) {
          console.log('路由失败。')
        }
      }
    )
    
    • RouterOptions

      • url:目标页面路径
      • params:传递的参数(可选)
    • RouterMode

      • Standard:标准实例模式
      • Single:单实例模式
    • 异常响应回调函数

      • 错误码 100001:内部错误,可能是渲染失败
      • 错误码 100002:路由地址错误
      • 错误码 100003:路由栈中页面超过32
  3. 目标页获取传递过来的参数

    params: any = router.getParams()
    
  4. 目标页返回上一页

    router.back()
    
  5. 目标页返回指定页,并携带参数

    router.back({
      url: 'pages/Index',
      params: { id: 10 }
    })
    

三、示例

  1. 代码目录结构

    |____src
    | |____main
    | | |____resources
    | | | | |____profile
    | | | | | |____main_pages.json
    | | | | |____media
    | | | | | |____back.png
    | | |____ets
    | | | |____components
    | | | | |____CommonComponents.ets
    | | | |____pages
    | | | | |____PageD.ets
    | | | | |____PageC.ets
    | | | | |____PageB.ets
    | | | | |____PageA.ets
    | | | | |____Index.ets
    
  2. main_pages.json

    {
      "src": [
        "pages/Index",
        "pages/PageA",
        "pages/PageB",
        "pages/PageC",
        "pages/PageD"
      ]
    }
    
  3. CommonComponents.ets

    import router from '@ohos.router'
    
    @Component
    export struct Header {
      @State params: any = router.getParams()
    
      build() {
        Row({ space: 5 }) {
          Image($r('app.media.back'))
            .width(30)
            .onClick(() => {
              // 返回前的警告
              router.showAlertBeforeBackPage({
                message: 'Show Alert Before Back Page'
              })
              // 返回上一页
              router.back()
            })
          if (this.params) {
            Text(`Params id: ${this.params.id}`)
              .fontSize(28)
              .fontWeight(FontWeight.Bold)
          }
        }
        .width('98%')
        .height(30)
      }
    }
    
  4. Index.ets

    import router from '@ohos.router'
    
    class RouterInfo {
      // 页面路径
      url: string
      // 页面标题
      title: string
    
      constructor(url: string, title: string) {
        this.url = url
        this.title = title
      }
    }
    
    @Entry
    @Component
    struct Index {
      @State message: string = '页面列表'
      private routers: RouterInfo[] = [
        new RouterInfo('pages/PageA', 'A页面'),
        new RouterInfo('pages/PageB', 'B页面'),
        new RouterInfo('pages/PageC', 'C页面'),
        new RouterInfo('pages/PageD', 'D页面')
      ]
    
      build() {
        Column() {
          Text(this.message)
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
            .height(80)
    
          List({ space: 15 }) {
            ForEach(
              this.routers,
              (router, index) => {
                ListItem() {
                  this.RouterItem(router, index + 1)
                }
              }
            )
          }
          .layoutWeight(1)
          .alignListItem(ListItemAlign.Center)
          .width('100%')
        }
        .width('100%')
        .height('100%')
      }
    
      @Builder
      RouterItem(r: RouterInfo, i: number) {
        Row() {
          Text(i + '. ')
            .fontSize(20)
            .fontColor(Color.White)
          Text(r.title)
            .fontSize(20)
            .fontColor(Color.White)
        }
        .width('90%')
        .padding(12)
        .backgroundColor('#38F')
        .borderRadius(20)
        .shadow({ radius: 6, color: '#4F000000', offsetX: 2, offsetY: 2 })
        .onClick(() => {
          // router 跳转
          router.pushUrl(
            {
              url: r.url,
              params: { id: i }
            },
            router.RouterMode.Single,
            err => {
              if (err) {
                console.log(`路由失败,errCode: ${err.code} errMsg: ${err.message}`)
              }
            }
          )
        })
      }
    }
    
  5. PageA.ets

    import { Header } from '../components/CommonComponents'
    
    @Entry
    @Component
    struct PageA {
      @State message: string = 'Page A'
    
      build() {
        Column() {
          Header()
          Row() {
            Column() {
              Text(this.message)
                .fontSize(50)
                .fontWeight(FontWeight.Bold)
            }
            .width('100%')
          }
          .height('100%')
        }.width('100%')
      }
    }
    
  6. 运行效果

请添加图片描述

四、总结

  1. 页面栈的最大容量上限为 32 个页面,使用 router.clear() 方法可以清空页面栈,释放内存。

  2. Router 有两种页面跳转模式,分别是:

    • router.pushUrl():目标页不会替换当前页,而是压入页面栈,因此可以用 router.back() 返回当前页。
    • router.replaceUrl():目标页替换当前页,当前页会被销毁并释放资源,无法返回当前页。
  3. Router 有两种页面实例模式,分别是:

    • Standard:标准实例模式,每次调整都会新建一个目标并压入栈顶。默认就是这种模式。
    • Single:单实例模式,如果目标页已经在栈中,则离栈顶最近的同 url 页面会被移动到栈顶并重新加载。
  4. router 的使用步骤:

    1. 导入 router 模块
    2. 使用 router 的 API

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1542950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NFTScan | 03.18~03.24 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期:2024.03.18~ 2024.03.24 NFT Hot News 01/ NFT 系列 NodeMonkes 地板价已超越 BAYC 3 月 18 日,据数据显示,NFT 系列 NodeMonkes 地板价已超越 Bored Ape Yacht …

C#宿舍信息管理系统

简介 功能 1.发布公告 2.地理信息与天气信息的弹窗 3.学生信息的增删改查 4.宿舍信息的增删改查 5.管理员信息的增删改查 6.学生对宿舍物品的报修与核实 7.学生提交请假与销假 8.管理员对保修的审批 9.管理员对请假的审批 技术 1.采用C#\Winform开发的C\S系统 2.采用MD5对数据…

python每日分析练习:电商平台用户行为数据洞察

模拟电商平台进行数据分析。数据分析最重要的是分析思路,工具是辅助,企业案例都是基于实际案例简单模拟后给出,只有通过实际的练习才能提高我们对数据的敏感度和分析能力,每天一个分析练习场景,一起打怪升级 场景与分…

(bug2总结)-mysql 字段为varchar,用int去查的时候可能会多返回数据

场景:表结构和数据如下图 查询语句如下 总结: mysql 字段为varchar,用int去查的时候可能会多返回数据。mysql版本为5.7.4

R语言迅速计算多基因评分(PRS)

Polygenic Risk Scores in R 最朴素的理解PRS: GWAS分析结果中,有每个SNP的beta值、se值、P值,因为GWAS分析中将SNP变为0-1-2编码,所以这些显著的SNP的beta值,就可以用于预测。 比如:GWAS分析中&#xf…

疲劳检测YOLOV8

疲劳检测YOLOV8,只需要OPENCV,采用YOLOV8训练得到PT模型,然后转换成ONNX,OPENCV调用,支持C/PYTHON/ANDROID开发疲劳检测YOLOV8

加速新能源汽车产品迭代:融合前沿科技的重要性

新能源汽车新质生产力提升咨询方案 一、新能源汽车企业行业目前发展现状及特点: 1、快速增长 2、技术迭代快 3、竞争加剧 二、新能源汽车企业发展新质生产力面临的痛点: 1、技术创新压力巨大 2、市场竞争激烈 3、供应链稳定性欠缺 4、成本控制压…

【等保测评机构】天津等保测评机构公司名单看这里!

天津等保测评机构公司名单看这里! 1、天津市兴先道科技有限公司 2、恒利德(天津)科技有限公司 3、中国民航大学(信息安全测评中心) 4、天津恒御科技有限公司 5、天津联信达软件技术有限公司 6、佰运俐&#xff0…

Java Day16 Servlet(二)

Servlet 1、继承结构2、ServletConfig对象3 、ServletContext3.1 获得路径3.2 域对象相关API 4、HttpServletRequest4.1 获得请求行和请求头相关api4.2 请求中键值对相关api 1、继承结构 顶级Servlet接口 //初始化void init(ServletConfig var1) throws ServletException; //…

【Redis】数据类型、事务执行、内存淘汰策略

目录 数据类型 Redis事务执行步骤 步骤: redis内存淘汰策略 设置内存淘汰策略 1.设置配置文件 2.通过命令设置 数据类型 官网解释 Understand Redis data types | Redis 首先,Redis 的所有键都是字符串,常用的数据类型有 5 种:Strin…

ArkTS编写的HarmonyOS原生聊天UI框架

简介 ChatUI,是一个ArkTS编写的HarmonyOS原生聊天UI框架,提供了开箱即用的聊天对话组件。 下载安装 ohpm install changwei/chatuiOpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包 接口和属性列表 接口列表 接…

算法系列--动态规划--子序列(1)

💕"深思熟虑的结果往往就是说不清楚。"💕 作者:Mylvzi 文章主要内容:算法系列–动态规划–子序列(2) 今天带来的是算法系列--动态规划--子序列(1),是子序列问题的开篇!带大家初识子序列问题 一.什么是子序列问题 我们…

【Burpsuite抓取APP、小程序数据包教程】

文章目录 一、抓取APP数据包1、burpsuite设置2、逍遥模拟器设置3、抓包即可 二、抓取小程序数据包1.bp设置代理端口2.利用火狐插件foxyproxy设置代理3.访问连接http://burp下载证书4.浏览器导入证书5.设置Proxifier6.配置代理规则7.进入小程序抓包 总结 一、抓取APP数据包 1、…

openGauss学习笔记-250 openGauss性能调优-使用Plan Hint进行调优-Join方式的Hint

文章目录 openGauss学习笔记-250 openGauss性能调优-使用Plan Hint进行调优-Join方式的Hint250.1 功能描述250.2 语法格式250.3 参数说明250.4 示例 openGauss学习笔记-250 openGauss性能调优-使用Plan Hint进行调优-Join方式的Hint 250.1 功能描述 指明Join使用的方法&#…

Intel被喷惨的大小核CPU终于有救,12、13代也沾了光

2021年 Intel 将混合架构引入 PC ,至今也没能让所有用户接受这一改动。 虽然 PE 核心设计 帮助我们更好理解鸡兔同笼问题 带来了额外的多线程性能提升,但对于游戏玩家们可就不那么友好了。 关了吧觉得亏,不关吧又要时不时担心大核偷懒、小核…

【数据结构取经之路】队列循环队列

目录 引言 队列的性质 队列的基本操作 初始化 判空 销毁 队列的长度 插入 删除 返回队头元素 循环队列 假溢出 空与满的判定 实现 初始化 插入 判空 销毁 删除 返回队列长度 返回队列头元素 判满 引言 队列和栈一样,也是数据结构的一种&…

蓝桥杯基础练习详细解析一(代码实现、解题思路、Python)

试题 基础练习 数列排序 资源限制 内存限制&#xff1a;512.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 给定一个长度为n的数列&#xff0c;将这个数列按从小到大的顺序排列。1<n<200 输入格式 第…

同城桶装水订水送水小程序:为水站打开新局面;

你是否还在为传统的电话、微信订水方式而烦恼&#xff1f;效率低下、管理混乱&#xff0c;是时候拥抱变革&#xff0c;让生意更上一层楼了&#xff01;同城送水小程序&#xff0c;一键解决你的所有痛点&#xff0c;让您的水站焕发新生。 水站系统功能亮点&#xff1a; 1. 一键…

无货源电商上货成功解析,如何选用采集和上货软件提高工作效力

最近大家是不是有一个疑惑&#xff1f;就是咱们在上货的过程中会出现解析失败 不论怎么上传&#xff0c;数据都是失败的&#xff0c;上传成功率很低很低&#xff0c;换了各种的上货软件 几百的几千的软件都用过了效果还是不行&#xff1f;和代理宣传的不符&#xff1f;什么日传…

如何成功将自己开发的APP上架到应用商店

如何成功将自己开发的APP上架到应用商店 随着移动应用市场的蓬勃发展&#xff0c;开发一款优秀的APP已成为许多企业和个人的首要选择。然而&#xff0c;成功上架并有效推广APP至关重要。本文将逐步介绍完整的上架流程&#xff0c;包括准备所需材料、注册开发者账户、进行APP备…