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

HarmonyOS笔记5:ArkUI框架的Navigation导航组件

ArkUI框架的Navigation导航组件

在移动应用中需要在不同的页面进行切换跳转。这种切换和跳转有两种方式:页面路由和Navigation组件实现导航。HarmonyOS推荐使用Navigation实现页面跳转。在本文中在HarmonyOS 5.0.0 Release SDK (API Version 12 Release)版本下,简单介绍ArkUI框架的Navigation导航组件。

一、Navigation组件定义的页面结构

Navigation组件主要包含​导航页和子页:

导航页由标题栏、内容区和工具栏组成,其中导航页可以通过hideNavBar属性进行隐藏,导航页不存在页面栈中,导航页和子页,以及子页之间可以通过路由操作进行切换。
在这里插入图片描述

二、定义导航页

Navigation是路由导航的根视图容器,一般作为页面(@Entry)的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换。
导航页页面的结构:

@Entry
@Component
struct NavigationPage {
@Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()//定义页面栈保存页面路径
build() {
    Column() {
      Navigation(this.pageInfos) {
        ...//内容区定义
      }
      .title("导航组件标题")//设置导航的标题
      .mode(NavigationMode.Stack)//配置导航的模式
      .navDestination(...)//设置导航路径
      .menus(...)//定义顶部菜单
      .toolbarConfiguration(...)//配置底部导航栏即工具栏
    }

说明:

1.在上述导航页中定义的NavPathStack对象表示页面栈,采用了@Provide装饰,可以看作是“提供”给后代的状态变量。在此处,它可以提供给子页同时使用页面栈,用于记录子页的导航路径。注意:导航页的路径不会推入到NavPathStack页面栈中。
2.导航页使用Navigation组件
3.在Navigation组件中:

(1)title()函数设置导航页的标题
(2)mode()函数配置导航的模式,NavigationMode.Stack表示单页显示模式,NavigationMode.Split表示分栏显示,NavigationMode.Auto表示自动选择显示模式
(3)navDestination()函数指定导航的路径,所有的导航路径可以通过PageMap来定义。形如:
@Builder
PageMap(routerName:string){
…//定义根据routerName路由名称不同调用不同的页面``
}

(4)menus()函数定义顶部菜单栏的内容,各个菜单项由NavigationMenuItem数组或CustomBuilder两种类型构成。菜单栏在竖屏最多支持显示3个图标,横屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。
(5)toolbarConfiguration()配置底部的工具栏。工具栏的单项由ToolbarItem组成,对toolbarConfiguration()函数传递ToolbarItem数组,可以生成底部工具栏的各个导航单项。

导航页的代码示例

@Entry
@Component
struct Index {
  //定义页面栈,子页也可以使用
  @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()
  //定义顶部菜单项,子页也可以使用
  @Provide topMenuItems:NavigationMenuItem[] = [
    {value: "首页", icon: 'resources/base/media/startIcon.png', action: ()=> {this.pageInfos.pushPath({ name: "首页"})}},
    {value: "配置", icon: 'resources/base/media/setting.png', action: ()=> {this.pageInfos.pushPath({ name: "配置"})}},
    {value: "帮助和支持", icon:'resources/base/media/help.png', action: ()=> {this.pageInfos.pushPath({ name: "帮助和支持"})}}]

  //定义底部工具栏
  @State bottomMenuItems:ToolbarItem[] = [
    {'value': "首页", 'icon': $r("app.media.startIcon"), 'action': ()=> {this.pageInfos.pushPath({ name: "首页"})}},
    {'value': "配置", 'icon': $r("app.media.setting"), 'action': ()=> {this.pageInfos.pushPath({ name: "配置"})}},
    {'value': "帮助和支持", 'icon': $r("app.media.help"), 'action': ()=> {this.pageInfos.pushPath({ name: "帮助和支持"})}}]

  //定义导航路径的数组,其中"退出“对应退出的操作
  private routerTitles:string[] = ["首页","配置","帮助和支持","退出"]

  @Builder
  PageMap(name: string) {
    if (name === "首页") {
      pageOne()
    } else if (name === "配置") {
      pageTwo()
    } else if (name === "帮助和支持") {
      pageThree()
    }
  }

  build() {
    Column() {
      Navigation(this.pageInfos) {
        //内容区,自行定义
        TextInput({ placeholder: '检索...' })
          .width("90%")
          .height(40)
          .backgroundColor('#FFFFFF')

        List({ space: 12 }) {
          ForEach(this.routerTitles,(item:string)=>{
            ListItem(){
              Text(item)
                .width("100%")
                .height(72)
                .backgroundColor('#D2E76B')
                .borderRadius(24)
                .fontSize(16)
                .fontWeight(500)
                .textAlign(TextAlign.Center)
                .onClick(()=>{
                  if(item=="退出"){
                    (getContext(this) as common.UIAbilityContext)?.terminateSelf();
                  }
                  else
                      this.pageInfos.pushPath({ name: item})
                })
            }
          })
        }
        .width("90%")
        .margin({ top: 12 })
      }
      .title("导航组件测试示例")//设置导航的标题
      .mode(NavigationMode.Stack)//配置导航的模式
      .navDestination(this.PageMap)//设置导航路径
      .menus(this.topMenuItems)//定义顶部菜单
      .toolbarConfiguration(this.bottomMenuItems)//配置底部工具栏
    }
    .height('100%').width('100%').backgroundColor('#83B5FF')
  }
}

在这里插入图片描述
图1 导航页的运行效果

三、定义子页

子页的结构:

@Component
export struct pageOne {
  @Consume('pageInfos') pageInfos: NavPathStack;   //引用
  build() {
    NavDestination() {
      //内容区定义
    }.title("首页")//定义子页的标题
    .onBackPressed(() => {
      const popDestinationInfo = this.pageInfos.pop() // 弹出页面栈栈顶元素
      return true
    })
  }
}

说明:

(1) 子页自定义组件不是页面的入口组件,无需使用@Entry装饰,也不需要在resources/base/profile/main_pages.json中配置页面。
(2)在子页中@Consume 装饰的变量,用于“消费(绑定)”导航页提供的导航路径堆栈。
(3)子页中使用NavDestination是子页面的根容器,用于定义子页面。

调用NavDestination的title()函数设置独立的标题栏。
调用NavDestination的menus()函数设置子页的顶部菜单栏。

子页代码示例

//PageOne.ets
@Component
export struct pageOne {
  @Consume('pageInfos') pageInfos: NavPathStack;//使用导航页的页面栈
  @Consume('topMenuItems') topMenuItems:NavigationMenuItem[]//使用导航页的菜单项的定义
  build() {
    NavDestination() {
      Column() {
       
      }.width('100%').height('100%').backgroundColor(Color.Orange)
    }.title("首页")
    .menus(this.topMenuItems)//定义顶部菜单栏的菜单项
    .onBackPressed(() => {
      this.pageInfos.pop() // 弹出页面栈栈顶元素
      return true
    })
  }
}

在这里插入图片描述
图2 子页1的运行效果

//PageTwo.ets
@Component
export struct pageTwo{
  @Consume('pageInfos') pageInfos: NavPathStack;
  @Consume('topMenuItems') topMenuItems:NavigationMenuItem[]
  build() {
    NavDestination() {
      Column() {
      }.width('100%').height('100%').backgroundColor(Color.Blue)
    }.title("配置")
    .menus(this.topMenuItems)
    .onBackPressed(() => {
      this.pageInfos.pop() // 弹出页面栈栈顶元素
      return true
    })
  }
}

在这里插入图片描述
图3 子页2的运行效果

//PageThree.ets
@Component
export struct pageThree{
  @Consume('pageInfos') pageInfos: NavPathStack;
  @Consume('topMenuItems') topMenuItems:NavigationMenuItem[]
  
  build() {
    NavDestination() {
      Column() {
        
      }.width('100%').height('100%').backgroundColor(Color.Green)
    }.title("帮助和支持")
    .menus(this.topMenuItems)
    .onBackPressed(() => {
      this.pageInfos.pop() // 弹出页面栈栈顶元素
      return true
    })
  }
}

在这里插入图片描述
图4 子页3的运行效果

四、页面的路由处理

页面的路由处理表示从不同页面中进行跳转和切换,通过NavPathStack页面栈来实现。下表中展示了NavPathStack页面栈的常见函数实现不同页面的处理操作

函数说明
pushPath({name:“pageOne”,param:“somevalue”}跳转到name属性指定的路径名对应的页面;param表示传递的参数,也可不用
pushPathByName(“pageOne”,“somevalue”)跳转到name属性指定的路径名对应的页面,可以传递参数值
pop()返回上一页
popToName(‘pageOne’)返回路由路径名为pageOne对应的页面
popToIndex(1)返回索引为1的页面
clear()返回到根首页,清除页面栈
replacePath({name:“pageOne”,param:“somevalue”} )替换页面
replacePathByName(“pageOne”,“somevalue”)替换页面
修改PageTwo.ets,使之增加图片,并为图片配置点击交互处理,当点击该图片返回到首页(对应pageOne页面),代码如下:
@Component
export struct pageTwo{
  @Consume('pageInfos') pageInfos: NavPathStack;
  @Consume('topMenuItems') topMenuItems:NavigationMenuItem[]
  build() {
    NavDestination() {
      Column() {
        Text("配置说明").fontSize(50).fontColor(Color.White)
        Image("resources/base/media/startIcon.png")
          .width(60)
          .height(60)
          .margin(5)
          .position({x:260,y:600})
          .onClick(() => {
            this.getUIContext()?.animateTo({ duration: 1000 }, () => {
              this.pageInfos.pushPath({ name: '首页' }, false)//返回首页
            })
          })
      }.width('100%').height('100%').backgroundColor(Color.Blue)
    }.title("配置")
    .menus(this.topMenuItems)
    .onBackPressed(() => {
      this.pageInfos.pop() // 弹出路由栈栈顶元素
      return true
    })
  }
}

在这里插入图片描述
图5 修改后的页面2运行结果
当点击图片后,会跳转到首页。当在首页页面的标题栏的返回按钮时,因为执行了this.pageInfos.pop(),仍会返回到上一级的页面,就是上述图5展示的页面。

参考文献:

1.单页面布局示意图 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-navigation-navigation-V5


http://www.kler.cn/a/406603.html

相关文章:

  • 2411rust,实现特征
  • 何以解忧-解决python问题的辛酸泪
  • java实现小程序接口返回Base64图片
  • [第五空间 2021]pklovecloud 详细题解
  • 【ASE】第八课_冰(ice)的效果
  • CSS3_BFC(十二)
  • 第 21 章 - Go lang反射机制
  • (python)unittest框架
  • 《线性代数的本质》
  • 拥抱极简主义前端开发:NoCss.js 引领无 CSS 编程潮流
  • 基于Springboot+Vue动漫推荐平台管理系统(源码+lw+讲解部署+PPT)
  • [NewStarCTF 2023]Include--详细解析
  • 设计模式之 观察者模式
  • 卷积神经网络(CNN)中的池化层(Pooling Layer)
  • oracle排查长时间没提交的事务造成的阻塞案例
  • SPA 单页面深入解读:优劣势剖析及实现方法
  • Qt自定义表格TableWidget实现整行单列按键逐行切换及跳转首尾
  • 【工控】线扫相机小结 第四篇
  • 2024内科学综合类科技核心期刊汇总
  • Pytorch使用手册-快速开始(专题一)
  • ArcGIS 10.2软件安装包下载及安装教程!
  • 美团面试:有哪些情况会产生死锁
  • Linux下Intel编译器oneAPI安装和链接MKL库编译
  • Android——连接MySQL(Java版)
  • 淘宝关键词订单API接口:电商运营的新利器
  • Python笔记2-六种标准数据类型3