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

鸿蒙UI(ArkUI-方舟UI框架)- 设置组件导航和页面路由

返回主章节 → 鸿蒙UI(ArkUI-方舟UI框架)

设置组件导航和页面路由

概述

组件导航(Navigation)和页面路由(@ohos.router)均支持应用内的页面跳转,但组件导航支持在组件内部进行跳转,使用更灵活。组件导航具备更强的一次开发多端部署能力,可以进行更加灵活的页面栈操作,同时支持更丰富的动效和生命周期。因此,推荐使用组件导航(Navigation)来实现页面跳转以及组件内的跳转,以获得更佳的使用体验。

组件导航(Navigation)(推荐)

组件导航(Navigation)主要用于实现页面间以及组件内部的页面跳转,支持在不同组件间传递跳转参数,提供灵活的跳转栈操作,从而更便捷地实现对不同页面的访问和复用。本文将从组件导航(Navigation)的显示模式、路由操作、子页面管理、跨包跳转以及跳转动效等几个方面进行详细介绍。

Navigation是路由导航的根视图容器,一般作为页面(@Entry)的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换,通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。一次开发,多端部署场景下,Navigation组件能够自动适配窗口显示大小,在窗口较大的场景下自动切换分栏展示效果。

Navigation组件主要包含​导航页和子页。导航页由标题栏(包含菜单栏)、内容区和工具栏组成,可以通过hideNavBar属性进行隐藏,导航页不存在页面栈中,与子页,以及子页之间可以通过路由操作进行切换。

设置页面显示模式

Navigation组件通过mode属性设置页面的显示模式

  • 自适应模式
    Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当页面宽度大于等于一定阈值( API version 9及以前:520vp,API version 10及以后:600vp )时,Navigation组件采用分栏模式,反之采用单栏模式。
Navigation(){
	//...
}
.mode(NavigationMode.Auto)
  • 单页面模式
    在这里插入图片描述
    将mode属性设置为Navigation

    Navigation() {
      // ...
    }
    .mode(NavigationMode.Stack)
    

在这里插入图片描述

  • 分栏模式
    在这里插入图片描述
    在这里插入图片描述

设置标题栏模式

标题栏在界面顶部,用于呈现界面名称和操作入口,Navigation组件通过titleMode属性设置标题栏模式。

说明
Navigation或NavDestination未设置主副标题并且没有返回键时,不显示标题栏。

  • Mini模式
    普通型标题栏,用于一级页面不需要突出标题的场景。
    在这里插入图片描述

    Navigation() {
      // ...
    }
    .titleMode(NavigationTitleMode.Mini)
    
  • Full模式
    强调型标题栏,用于一级页面需要突出标题的场景。
    在这里插入图片描述

    Navigation() {
      // ...
    }
    .titleMode(NavigationTitleMode.Full)
    

设置菜单栏

菜单栏位于Navigation组件的右上角,开发者可以通过menus属性进行设置。menus支持Array< NavigationMenuItem>和CustomBuilder两种参数类型。使用Array< NavigationMenuItem>类型时,竖屏最多支持显示3个图标,横屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。
在这里插入图片描述

let TooTmp: NavigationMenuItem = {'value': "", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}
Navigation() {
  // ...
}
.menus([TooTmp,
  TooTmp,
  TooTmp])

图片也可以引用resources中的资源。

let TooTmp : NavigationMenuItem = {'value':"",'icon':"resources/base/media/ic_public_highlights.svg",'action':()=>{}}
Navigation(){
	//...
}
.menus([
	TooTmp,
	TooTmp,
	TooTmp
])

如果设置了4个图标的菜单栏,则多余的会自动生成图标:
在这里插入图片描述

设置工具栏

工具栏位于Navigation组件的底部,开发者可以通过toolbarConfiguration属性进行设置。
在这里插入图片描述

let ToolTmp:ToolbarItem = {'value':"",'icon':"",'action':()=>{}}
let ToolBar:ToolbarItem[] = [ToolTmp,ToolTmp,ToolTmp];
Navitation(){
}.toolbarConfiguration(ToolBar)

路由操作

Navigation路由相关的操作都是基于页面栈NavPathStack提供的方法进行,每个Navigation都需要创建并传入一个NavPathStack对象,用于管理页面。主要涉及页面跳转、页面返回、页面替换、页面删除、参数获取、路由拦截等功能。

说明
不建议开发者通过监听生命周期的方式管理自己的页面栈。

@Entity
@Component
struct Index{
	//创建一个页面栈对象并传入Navigation中
	pageStack: NavPathStack = new NavPatStack()
	build(){
		Navigation(this.pageStack){
		}
		.title('Main')
	}
}
页面跳转

NavPathStack通过Push相关的接口去实现页面跳转的功能,主要分为以下三类:

  1. 普通跳转,通过页面的name去跳转,并可以携带param

    this.pageStack.pushPat({name:'PageOne',param:'PageOne Param'})
    this.pageStack.pushPathByName('PageOne','PageOne Param')
    
  2. 带返回回调的跳转,跳转时添加onPop回调,能在页面出栈时获取返回信息,并进行处理

    this.pageStack.pushPathByName('PageOne','PageOne Param',(popInfo)=>{
    	  console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result))
    
    })
    
  3. 带错误码的跳转,跳转结束会触发异步回调,返回错误码信息。

    this.pageStack.pushDestination({name: "PageOne", param: "PageOne Param"})
      .catch((error: BusinessError) => {
        console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
      }).then(() => {
        console.info('Push destination succeed.');
      });
    this.pageStack.pushDestinationByName("PageOne", "PageOne Param")
      .catch((error: BusinessError) => {
        console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
      }).then(() => {
        console.info('Push destination succeed.');
      });
    
页面返回

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

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

NavPathStack通过Replace相关接口去实现页面替换功能。

//将栈顶的页面替换为PageOne
this.pageStack.replace({name:'PageOne',param:'PageOne Param})
this.pageStack.replaceByName('PageOne','PageOne Param')
//带错误码的替换,跳转结束会触发异步回调,返回错误码信息
this.pageStack.replaceDestination({name:'',param:''})
.catch((error: BusinessError)=>{
	    console.error(`Replace destination failed, error code = ${error.code}, error.message = ${error.message}.`);

}).then(()=>{
	console.info()
})
页面删除

NavPathStack通过Remove相关接口去实现删除页面栈中特定页面的功能。

//删除栈中name为pageOne的所有页面
this.pageStack.removeByName("PageOne");
//删除指定索引的页面
this.pageStack.removeByIndexes([1,3,5])
//删除指定id的页面
this.pageStack.removeByNavDestinationId("1")
移动页面

NavPathStack通过Move相关接口去实现移动页面栈中特定页面到栈顶的功能。

//移动栈中name为PageOne的页面到栈顶
this.pageStack.moveToTop("PageOne")
//移动栈中索引为1的页面到栈顶
this.pageStack.moveIndexToTop(1)
参数获取

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

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

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

说明
无论是哪个回调,在进入回调时页面栈都已经发生了变化。

开发者可以在willShow回调中通过修改路由栈来实现路由拦截重定向的能力。

this.pageStack.setInterception({
	willSow: (from:NavDestinationContext | "navBar",to:NavDestinationContext | "navBar",operation: NavigationOperation,animated:boolean)=>{
		if (typeof to === "string") {
	      console.log("target page is navigation home page.");
	      return;
	    }
	    // 将跳转到PageTwo的路由重定向到PageOne
	    let target: NavDestinationContext = to as NavDestinationContext;
	    if (target.pathInfo.name === 'PageTwo') {
	      target.pathStack.pop();
	      target.pathStack.pushPathByName('PageOne', null);
	    }
	}
})

子页面

NavDestinationNavigation子页面的根容器,用于承载子页面的一些特殊属性以及生命周期等。NavDestination可以设置独立的标题栏和菜单栏等属性,使用方法与Navigation相同。NavDestination也可以通过mode属性设置不同的显示类型,用于满足不同页面的诉求。

页面显示类型
  • 标准类型
    NavDestination组件默认为标准类型,此时mode属性为NavDestinationMode.STANDARD。标准类型的NavDestination的生命周期跟随其在NavPathStack页面栈中的位置变化而改变。
  • 弹窗类型
    NavDestination设置mode为NavDestinationMode.DIALOG弹窗类型,此时整个NavDestination默认透明显示。弹窗类型的NavDestination显示和消失时不会影响下层标准类型的NavDestination的显示和生命周期,两者可以同时显示。
    // Dialog NavDestination
    @Entry
    @Component
     struct Index {
       @Provide('NavPathStack') pageStack: NavPathStack = new NavPathStack()
    
       @Builder
       PagesMap(name: string) {
         if (name == 'DialogPage') {
           DialogPage()
         }
       }
    
       build() {
         Navigation(this.pageStack) {
           Button('Push DialogPage')
             .margin(20)
             .width('80%')
             .onClick(() => {
               this.pageStack.pushPathByName('DialogPage', '');
             })
         }
         .mode(NavigationMode.Stack)
         .title('Main')
         .navDestination(this.PagesMap)
       }
     }
    
     @Component
     export struct DialogPage {
       @Consume('NavPathStack') pageStack: NavPathStack;
    
       build() {
         NavDestination() {
           Stack({ alignContent: Alignment.Center }) {
             Column() {
               Text("Dialog NavDestination")
                 .fontSize(20)
                 .margin({ bottom: 100 })
               Button("Close").onClick(() => {
                 this.pageStack.pop()
               }).width('30%')
             }
             .justifyContent(FlexAlign.Center)
             .backgroundColor(Color.White)
             .borderRadius(10)
             .height('30%')
             .width('80%')
           }.height("100%").width('100%')
         }
         .backgroundColor('rgba(0,0,0,0.5)')
         .hideTitleBar(true)
         .mode(NavDestinationMode.DIALOG)
       }
     }
    
    在这里插入图片描述
页面生命周期

Navigation作为路由容器,其生命周期承载在NavDestination组件上,以组件事件的形式开放。
其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期。其中,aboutToAppear和aboutToDisappear是自定义组件的生命周期(NavDestination外层包含的自定义组件),OnAppear和OnDisappear是组件的通用生命周期。剩下的六个生命周期为NavDestination独有。
在这里插入图片描述
在这里插入图片描述

页面监听和查询

为了方便组件跟页面解耦,在NavDestination子页面内部的自定义组件可以通过全局方法监听或查询到页面的一些状态信息

  • 页面信息查询
    自定义组件提供queryNavDestinationInfo方法,可以在NavDestination内部查询到当前所属页面的信息,返回值为NavDestinationInfo,若查询不到则返回undefined。

     import { uiObserver } from '@kit.ArkUI';
    
     // NavDestination内的自定义组件
     @Component
     struct MyComponent {
       navDesInfo: uiObserver.NavDestinationInfo | undefined
    
       aboutToAppear(): void {
         this.navDesInfo = this.queryNavDestinationInfo();
       }
    
       build() {
           Column() {
             Text("所属页面Name: " + this.navDesInfo?.name)
           }.width('100%').height('100%')
       }
     }
    
  • 页面状态监听
    通过observer.on(‘navDestinationUpdate’) 提供的注册接口可以注册NavDestination生命周期变化的监听,使用方式如下:

    uiObserver.on('navDestinationUpdate', (info) => {
         console.info('NavDestination state update', JSON.stringify(info));
     });
    

    也可以注册页面切换的状态回调,能在页面发生路由切换的时候拿到对应的页面信息NavDestinationSwitchInfo,并且提供了UIAbilityContext和UIContext不同范围的监听:

     // 在UIAbility中使用
     import { UIContext, uiObserver } from '@kit.ArkUI';
    
     // callBackFunc 是开发者定义的监听回调函数
     function callBackFunc(info: uiObserver.NavDestinationSwitchInfo) {}
     uiObserver.on('navDestinationSwitch', this.context, callBackFunc);
    
     // 可以通过窗口的getUIContext()方法获取对应的UIContent
     uiContext: UIContext | null = null;
     uiObserver.on('navDestinationSwitch', this.uiContext, callBackFunc);
    

页面转场

Navigation默认提供了页面切换的转场动画,通过页面栈操作时,会触发不同的转场效果(API version 13之前,Dialog类型的页面默认无转场动画。从API version13开始,Dialog类型的页面支持系统转场动画。),Navigation也提供了关闭系统转场、自定义转场以及共享元素转场的能力。

关闭转场
  • 全局关闭
    Navigation通过NavPathStack中提供的disableAnimation方法可以在当前Navigation中关闭或打开所有转场动画

    pageStack: NavPathStack = new NavPathStack()
    
    aboutToAppear(): void {
      this.pageStack.disableAnimation(true)
    }
    
  • 单次关闭
    NavPathStack中提供的Push、Pop、Replace等接口中可以设置animated参数,默认为true表示有转场动画,需要单次关闭转场动画可以置为false,不影响下次转场动画。

    pageStack: NavPathStack = new NavPathStack()
    
    this.pageStack.pushPath({ name: "PageOne" }, false)
    this.pageStack.pop(false)
    
自定义转场

在这里插入图片描述
具体示例代码可以参考Navigation自定义转场示例。

共享元素转场

NavDestination之间切换时可以通过geometryTransition实现共享元素转场。配置了共享元素转场的页面同时需要关闭系统默认的转场动画

  1. 为需要实现共享元素转场的组件添加geometryTransition属性,id参数必须在两个NavDestination之间保持一致。

    // 起始页配置共享元素id
    NavDestination() {
      Column() {
        // ...
        Image($r('app.media.startIcon'))
        .geometryTransition('sharedId')
        .width(100)
        .height(100)
      }
    }
    .title('FromPage')
    
    // 目的页配置共享元素id
    NavDestination() {
      Column() {
        // ...
        Image($r('app.media.startIcon'))
        .geometryTransition('sharedId')
        .width(200)
        .height(200)
      }
    }
    .title('ToPage')
    
  2. 将页面路由的操作,放到animateTo动画闭包中,配置对应的动画参数以及关闭系统默认的转场。

    NavDestination() {
      Column() {
        Button('跳转目的页')
        .width('80%')
        .height(40)
        .margin(20)
        .onClick(() => {
            this.getUIContext()?.animateTo({ duration: 1000 }, () => {
              this.pageStack.pushPath({ name: 'ToPage' }, false)
            })
        })
      }
    }
    .title('FromPage')
    

挎包动态路由

示例代码

导航转场

导航转场是页面的路由转场方式,也就是一个界面消失,另外一个界面出现的动画效果。开发者也可以自定义导航转场的动画效果,具体请参考Navigation示例3。

导航转场推荐使用Navigation组件实现,可搭配NavDestination组件实现导航功能。

创建导航页

实现步骤为:
1.使用Navigation创建导航主页,并创建路由栈NavPathStack以此来实现不同页面之间的跳转。
2.在Navigation中增加List组件,来定义导航主页中不同的一级界面。
3.在List内的组件添加onClick方法,并在其中使用路由栈NavPathStack的pushPathByName方法,使组件可以在点击之后从当前页面跳转到输入参数name在路由表内对应的页面。

//PageOne.ets
@Entry
@Component
struct NavigationDemo {
  @Provide('pathInfos') pathInfos: NavPathStack = new NavPathStack();
  private listArray: Array<string> = ['WLAN', 'Bluetooth', 'Personal Hotpot', 'Connect & Share'];

  build() {
    Column() {
      Navigation(this.pathInfos) {
        TextInput({ placeholder: '输入关键字搜索' })
          .width('90%')
          .height(40)
          .margin({ bottom: 10 })

        // 通过List定义导航的一级界面
        List({ space: 12, initialIndex: 0 }) {
          ForEach(this.listArray, (item: string) => {
            ListItem() {
              Row() {
                Row() {
                  Text(`${item.slice(0, 1)}`)
                    .fontColor(Color.White)
                    .fontSize(14)
                    .fontWeight(FontWeight.Bold)
                }
                .width(30)
                .height(30)
                .backgroundColor('#a8a8a8')
                .margin({ right: 20 })
                .borderRadius(20)
                .justifyContent(FlexAlign.Center)

                Column() {
                  Text(item)
                    .fontSize(16)
                    .margin({ bottom: 5 })
                }
                .alignItems(HorizontalAlign.Start)

                Blank()

                Row()
                  .width(12)
                  .height(12)
                  .margin({ right: 15 })
                  .border({
                    width: { top: 2, right: 2 },
                    color: 0xcccccc
                  })
                  .rotate({ angle: 45 })
              }
              .borderRadius(15)
              .shadow({ radius: 100, color: '#ededed' })
              .width('90%')
              .alignItems(VerticalAlign.Center)
              .padding({ left: 15, top: 15, bottom: 15 })
              .backgroundColor(Color.White)
            }
            .width('100%')
            .onClick(() => {
              this.pathInfos.pushPathByName(`${item}`, '详情页面参数')//将name指定的NaviDestination页面信息入栈,传递的参数为param
            })
          }, (item: string): string => item)
        }
        .listDirection(Axis.Vertical)
        .edgeEffect(EdgeEffect.Spring)
        .sticky(StickyStyle.Header)
        .chainAnimation(false)
        .width('100%')
      }
      .width('100%')
      .mode(NavigationMode.Auto)
      .title('设置') // 设置标题文字
    }
    .size({ width: '100%', height: '100%' })
    .backgroundColor(0xf4f4f5)
  }
}

创建导航子页

导航子页1实现步骤

1.使用NavDestination,来创建导航子页CommonPage。

2.创建路由栈NavPathStack并在onReady时进行初始化,获取当前所在的页面栈,以此来实现不同页面之间的跳转。

3.在子页面内的组件添加onClick,并在其中使用路由栈NavPathStack的pop方法,使组件可以在点击之后弹出路由栈栈顶元素实现页面的返回。

//PageOne.ets
........
此处省略 NavigationDemo 导航主页代码,,,
........

@Builder
export function MyCommonPageBuilder(name: string, param: string) {
  MyCommonPage({ name: name, value: param })
}

@Component
export struct MyCommonPage {
  pathInfos: NavPathStack = new NavPathStack();
  name: String = '';
  @State value: String = '';

  build() {
    NavDestination() {
      Column() {
        Text(`${this.name}设置页面`)
          .width('100%')
          .fontSize(20)
          .fontColor(0x333333)
          .textAlign(TextAlign.Center)
          .textShadow({
            radius: 2,
            offsetX: 4,
            offsetY: 4,
            color: 0x909399
          })
          .padding({ top: 30 })
        Text(`${JSON.stringify(this.value)}`)
          .width('100%')
          .fontSize(18)
          .fontColor(0x666666)
          .textAlign(TextAlign.Center)
          .padding({ top: 45 })
        Button('返回')
          .width('50%')
          .height(40)
          .margin({ top: 50 })
          .onClick(() => {
            //弹出路由栈栈顶元素,返回上个页面
            this.pathInfos.pop();
          })
      }
      .size({ width: '100%', height: '100%' })
    }.title(`${this.name}`)
    .onReady((ctx: NavDestinationContext) => {
      //NavDestinationContext获取当前所在的页面栈
      this.pathInfos = ctx.pathStack;
    }) 

  }
}


导航子页2实现步骤

1.使用NavDestination,来创建导航子页SharePage。

2.创建路由栈NavPathStack并在onReady时进行初始化,获取当前所在的页面栈,以此来实现不同页面之间的跳转。

3.在子页面内的组件添加onClick,并在其中使用路由栈NavPathStack的pushPathByName方法,使组件可以在点击之后从当前页面跳转到输入参数name在路由表内对应的页面。

........
此处省略 NavigationDemo 导航主页代码,,,
........

........
此处省略 CommonPage 导航子页代码,,,
........
//PageTwo.ets
@Builder
export function MySharePageBuilder(name: string, param: string) {
  MySharePage({ name: name })
}

@Component
export struct MySharePage {
  pathInfos: NavPathStack = new NavPathStack();
  name: String = '';
  private listArray: Array<string> = ['Projection', 'Print', 'VPN', 'Private DNS', 'NFC'];

  build() {
    NavDestination() {
      Column() {
        List({ space: 12, initialIndex: 0 }) {
          ForEach(this.listArray, (item: string) => {
            ListItem() {
              Row() {
                Row() {
                  Text(`${item.slice(0, 1)}`)
                    .fontColor(Color.White)
                    .fontSize(14)
                    .fontWeight(FontWeight.Bold)
                }
                .width(30)
                .height(30)
                .backgroundColor('#a8a8a8')
                .margin({ right: 20 })
                .borderRadius(20)
                .justifyContent(FlexAlign.Center)

                Column() {
                  Text(item)
                    .fontSize(16)
                    .margin({ bottom: 5 })
                }
                .alignItems(HorizontalAlign.Start)

                Blank()

                Row()
                  .width(12)
                  .height(12)
                  .margin({ right: 15 })
                  .border({
                    width: { top: 2, right: 2 },
                    color: 0xcccccc
                  })
                  .rotate({ angle: 45 })
              }
              .borderRadius(15)
              .shadow({ radius: 100, color: '#ededed' })
              .width('90%')
              .alignItems(VerticalAlign.Center)
              .padding({ left: 15, top: 15, bottom: 15 })
              .backgroundColor(Color.White)
            }
            .width('100%')
            .onClick(() => {
              this.pathInfos.pushPathByName(`${item}`, '页面设置参数')
            })
          }, (item: string): string => item)
        }
        .listDirection(Axis.Vertical)
        .edgeEffect(EdgeEffect.Spring)
        .sticky(StickyStyle.Header)
        .width('100%')
      }
      .size({ width: '100%', height: '100%' })
    }.title(`${this.name}`)
    .onReady((ctx: NavDestinationContext) => {
      //NavDestinationContext获取当前所在的页面栈
      this.pathInfos = ctx.pathStack;
    }) 
  }
}

创建路由跳转

1.工程配置文件module.json5中配置 “routerMap”: “$profile:route_map”。
在这里插入图片描述

2.route_map.json中配置全局路由表,路由栈NavPathStack可根据路由表中的name将对应页面信息入栈。
在这里插入图片描述

{
  "routerMap" : [
    {
      "name" : "WLAN",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "Bluetooth",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "Personal Hotpot",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "Connect & Share",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MySharePageBuilder"
    },
    {
      "name" : "Projection",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "Print",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "VPN",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "Private DNS",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    },
    {
      "name" : "NFC",
      "pageSourceFile"  : "src/main/ets/pages/NavigationDemo.ets",
      "buildFunction" : "MyCommonPageBuilder"
    }
  ]
}

效果如下:
在这里插入图片描述

页面路由(@ohos.router)(不推荐)

Router切换Navigation

鉴于组件导航(Navigation)支持更丰富的动效、一次开发多端部署能力和更灵活的栈操作。本文主要从页面跳转、动效和生命周期等方面介绍如何从Router切换到Navigation。


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

相关文章:

  • Nginx进阶篇 - nginx多进程架构详解
  • 【万字详细教程】Linux to go——装在移动硬盘里的Linux系统(Ubuntu22.04)制作流程;一口气解决系统安装引导文件迁移显卡驱动安装等问题
  • 解释一下数据库中的事务隔离级别,在 Java 中如何通过 JDBC设置事务隔离级别?
  • Windows Docker笔记-简介摘录
  • HAL库 Systick定时器 基于STM32F103EZT6 野火霸道,可做参考
  • QUIC 与 UDP 关系
  • 青少年编程与数学 02-008 Pyhon语言编程基础 24课题、正则表达式
  • MES系统对于中小型制造企业有什么价值?
  • verilog练习:8bit移位寄存器
  • 防火墙与Squid代理服务器
  • FastReport 加载Load(Stream) 模板内包含换行符不能展示
  • 【网络】应用层协议http
  • 避免样式冲突:掌握CSS选择器优先级与层叠规则的终极指南
  • Itext pdf reader解析
  • mysql的语句备份详解
  • 11.享元模式 (Flyweight)
  • windows同时安装两个不同版本的Mysql
  • C++ ——— 多态的概念及其原理和实现
  • BGP边界网关协议(Border Gateway Protocol)选路、属性(一)
  • 使用 java -jar 命令启动 Spring Boot 应用时,指定特定的配置文件的几种实现方式
  • QWidget中嵌入QQuickWidget,从qml端鼠标获取经纬度点(double类型),发到c++端。把c++端的对象暴露个qml端调用
  • 第九天 动手实践ArkTS,创建简单的UI组件
  • BFS算法——广度优先搜索,探索未知的旅程(下)
  • 陶氏环面包络减速机:为工业视觉检测注入“精准动力”!
  • 【机器学习】深入探索SVM概念及其核方法
  • 3NF讲解