Navigation组件

一、Navigation组件介绍

Navigation组件一般作为页面的根容器,包括单页面、分栏和自适应三种显示模式。同时,Navigation提供了属性,来设置页面的标题栏、工真栏、导航栏等。

Navigation组件的页面包含主页和内容页。主页由标题栏、内容区和工具栏组成,可在内容区中使用NavRouter子组件实现导航栏功能。内容页主要显示NavDestination子组件中的内容。NavRouter是配合Navigation使用的特殊子组件,默认提供点击响应处理,不需要开发者自定义点击事件逻辑,NavRouter有且仅有两个子组件,其中第二个子组件必须是NavDestination。

NavDestination是配合NavRouter使用的特殊子组件,用于显示Navigation组件的内容页。当开发者点击NavRouter组件时,会跳转到对应的NavDestination内容区。

二、接口

2.1.接口:

Navigation()

2.2.参数:

参数名参数类型必填参数描述
pathInfos NavPathStack 路由栈信息。

NavigationType枚举说明

名称枚举值描述
Push 1 跳转到应用内的指定页面。
Replace 2 用应用内的某个页面替换当前页面,并销毁被替换的页面。
Back 3 返回到指定的页面。指定的页面不存在栈中时不响应。未传入指定的页面时返回上一页。

2.3.属性

支持以下属性:

名称参数类型描述
title ResourceStr10+ | CustomBuilderNavigationCommonTitle9+ | NavigationCustomTitle9+

页面标题。

说明:

使用NavigationCustomTitle类型设置height高度时,titleMode属性不会生效。

字符串超长时,如果不设置副标题,先缩小再换行(2行)最后...截断。如果设置副标题,先缩小最后...截断。

subTitle(deprecated) string 页面副标题。不设置时不显示副标题。从API Version 9开始废弃,建议使用title代替。
menus Array<NavigationMenuItem> | CustomBuilder 页面右上角菜单。不设置时不显示菜单项。使用Array<NavigationMenuItem> 写法时,竖屏最多支持显示3个图标,横屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。
titleMode NavigationTitleMode

页面标题栏显示模式。

默认值:NavigationTitleMode.Free

toolBar(deprecated) object | CustomBuilder

设置工具栏内容。不设置时不显示工具栏。

items: 工具栏所有项。

说明:

items均分底部工具栏,在每个均分内容区布局文本和图标,文本超长时,逐级缩小,缩小之后换行,最后...截断。

从API version 10开始,该接口不再维护,推荐使用toolbarConfiguration代替。

toolbarConfiguration10+ Array<ToolbarItem> | CustomBuilder

设置工具栏内容。不设置时不显示工具栏。

说明:

使用Array<ToolbarItem>写法设置的工具栏有如下特性:

工具栏所有选项均分底部工具栏,在每个均分内容区布局文本和图标。

文本超长时,若工具栏选项个数小于5个,优先拓展选项的宽度,最大宽度与屏幕等宽,其次逐级缩小,缩小之后换行,最后...截断。

竖屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。横屏下必须配合menus属性的Array<NavigationMenuItem>使用,底部工具栏会自动隐藏,同时底部工具栏所有选项移动至页面右上角菜单。

使用CustomBuilder写法为用户自定义工具栏选项,除均分底部工具栏外不具备以上功能。

hideToolBar boolean

隐藏工具栏。

默认值:false

true: 隐藏工具栏。

false: 显示工具栏。

hideTitleBar boolean

隐藏标题栏。

默认值:false

true: 隐藏标题栏。

false: 显示标题栏。

hideBackButton boolean

隐藏标题栏中的返回键。 不支持隐藏NavDestination组件标题栏中的返回键。

默认值:false

true: 隐藏返回键。

false: 显示返回键。

说明:

返回键仅针对titleMode为NavigationTitleMode.Mini时才生效。

navBarWidth9+ Length

导航栏宽度。

默认值:240

单位:vp

说明:

仅在Navigation组件分栏时生效。

navBarPosition9+ NavBarPosition

导航栏位置。

默认值:NavBarPosition.Start

说明:

仅在Navigation组件分栏时生效。

mode9+ NavigationMode

导航栏的显示模式。

默认值:NavigationMode.Auto

自适应:基于组件宽度自适应单栏和双栏。

说明:

支持Stack、Split与Auto模式。

backButtonIcon9+ string | PixelMap | Resource 设置标题栏中返回键图标。
hideNavBar9+ boolean

是否隐藏导航栏。设置为true时,隐藏Navigation的导航栏,包括标题栏、内容区和工具栏。如果此时路由栈中存在NavDestination页面,则直接显示栈顶NavDestination页面,反之显示空白。从API Version 9开始到API Version 10仅在双栏模式下生效。从API Version 11开始在单栏、双栏与自适应模式均生效。

默认值:false

navDestination10+ builder: (name: string, param: unknown) => void

创建NavDestination组件。

说明:

使用builder函数,基于name和param构造NavDestination组件。builder中允许在NavDestination组件外包含一层自定义组件, 但自定义组件不允许设置属性和事件,否则仅显示空白。

navBarWidthRange10+ [DimensionDimension]

导航栏最小和最大宽度(双栏模式下生效)。

默认值:最小默认值 240,最大默认值为组件宽度的40% ,且不大于 432,如果只设置一个值,则未设置的值按照默认值计算。

单位:vp

规则:优先级规则详见说明。

minContentWidth10+ Dimension

导航栏内容区最小宽度(双栏模式下生效)。

默认值:360

单位:vp

规则:优先级规则详见说明。

Auto模式断点计算:默认600vp,minNavBarWidth(240vp) + minContentWidth (360vp)

说明
  1. 仅设置navBarWidth,不支持Navigation分割线拖拽。

  2. navBarWidthRange指定分割线可以拖拽范围。如果不设置值,则按照默认值处理。拖拽范围需要满足navBarWidthRange设置的范围和minContentWidth限制。

  3. Navigation显示范围缩小:a. 缩小内容区大小。如果不设置minContentWidth属性,则可以缩小内容区至0, 否则最小缩小至minContentWidth。b. 缩小导航栏大小,缩小时需要满足导航栏宽度大于navBarRange的下限。c. 对显示内容进行裁切。

2.4.事件

名称功能描述
onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void) 当titleMode为NavigationTitleMode.Free时,随着可滚动组件的滑动标题栏模式发生变化时触发此回调。
onNavBarStateChange(callback: (isVisible: boolean) => void) 9+ 导航栏显示状态切换时触发该回调。返回值isVisible为true时表示显示,为false时表示隐藏。
onNavigationModeChange(callback: (mode: NavigationMode) => void) 11+

当Navigation首次显示或者单双栏状态发生变化时触发该回调。

NavigationMode.Split: 当前Navigation显示为双栏;

NavigationMode.Stack: 当前Navigation显示为单栏。

customNavContentTransition(delegate(from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation): NavigationAnimatedTransition | undefined 11+

自定义转场动画回调。

from: 退场Destination的页面参数;

to: 进场Destination的页面参数;

operation: 转场类型;

undefined: 返回未定义,执行默认转场动效。

三、模式说明

3.1.单页模式

可以提供Tabs选项卡、标题、menu菜单页面,点击页面跳转的时候,会直接覆盖到当前页面。

 

3.2.分栏模式

分栏模式也可以提供Tabs选项卡、标题、menu菜单页面,点击页面跳转的时候,是折叠屏、平板新的页面会直接显示在另一半屏幕。

四、案例

1)实现类似于华为笔记的软件功能,代码如下:

class Note{
  title:string;
  content:string;

  constructor(title:string, content:string) {
    this.title = title;
    this.content = content;
  }
}

@Entry
@Component
struct NavigationDemo {

  /**
   * 初始化值,作为页面索引使用
   */
  @State index: number = 0;

  /**
   * 准备假数据,作为笔记信息展示
   */
  @State noteList:Note[] = [
    new Note("springboot", "springboot是一门优秀的框架"),
    new Note("spring", "spring是一门优秀的框架"),
    new Note("springmvc", "springmvc是一门优秀的框架"),
    new Note("springcloud", "springcloud是一门优秀的框架"),
  ]


  @Builder toolbar() {// 通过builder自定义toolbar
    Row() {
      Column() {
        Image(this.index == 0 ? $r("app.media.icon_pending_selected") : $r("app.media.icon_pending_normal"))
          .size({width: 25, height: 25})
        Text('笔记')
          .fontSize(16)
          .fontColor(this.index == 0 ? "#2a58d0" : "#6b6b6b")
      }
      .alignItems(HorizontalAlign.Center)
      .height('100%')
      .layoutWeight(1)
      .onClick(() => {
        this.index = 0;
      })

      Column() {
        Image(this.index == 1 ? $r("app.media.icon_pending_selected") : $r("app.media.icon_pending_normal"))
          .size({width: 25, height: 25})
        Text('待办')
          .fontSize(16)
          .fontColor(this.index == 1 ? "#2a58d0" : "#6b6b6b")
      }
      .alignItems(HorizontalAlign.Center)
      .height('100%')
      .layoutWeight(1)
      .onClick(() => {
        this.index = 1;
      })
    }
    .width('100%')
    .height(45)
    .alignItems(VerticalAlign.Center)
  }

  build() {
    Navigation(){
      List(){
        ForEach(this.noteList, (item:Note)=>{
          ListItem(){
            /**
             * NavRouter导航组件,默认提供点击响应处理,不需要开发者自定义点击事件逻辑。
             * 必须包含两个子组件,其中第二个子组件必须为NavDestination。
             */
            NavRouter(){

              Row(){
                Text(item.title).fontSize(16)
                Text(item.content).fontSize(13).opacity(0.5)
              }
              .width("100%")
              .height(90)
              .borderRadius(10)
              .backgroundColor(Color.White)
              .padding({left:15, right:15})
              .margin({top:15})

              /**
               * 作为子页面的根容器,用于显示Navigation的内容区。这里控制的点击进入的新页面的内容
               */
              NavDestination(){
                ContentComponent()
              }.title("文章详情页面")
            }
          }
        })
      }
    }
    .width("100%")
    .height("100%")
    .title("全部课程") //标题
    .menus([
      {
        value:"",//菜单文字描述
        icon:"./images/three_point.svg", //菜单的图标,必须是字符串,不能直接使用media 下的文字
        action: ()=> { //点击后触发的事件
          console.log("-------------------------search")
        }
      }
    ])
    /*.toolbarConfiguration([ //设置工具栏内容。不设置时不显示工具栏。跟tabs一致
      {value:"笔记",
        icon: $r("app.media.note"),//默认图标
        //status: ToolbarItemStatus.ACTIVE,//工具栏单个选项的状态。设置工具栏单个选项为ACTIVE态, 该选项通过点击事件可以将icon图标更新为activeIcon对应的图片资源。
        //activeIcon:$r("app.media.note_seleted"), //点击选中时的图标
        action:()=>{
          console.log("hello123");
      }},
      {value:"待办",
        icon:$r("app.media.pending"),//默认图标
        //status: ToolbarItemStatus.ACTIVE,//工具栏单个选项的状态。设置工具栏单个选项为ACTIVE态, 该选项通过点击事件可以将icon图标更新为activeIcon对应的图片资源。
        //activeIcon:$r("app.media.pending_seleted"), //点击选中时的图标
        action:()=>{
          console.log("world123");
      }}
    ])*/
    .toolbarConfiguration(this.toolbar())// 可以指定定义控制器实现和tabs一样的切换
    .titleMode(NavigationTitleMode.Mini) //导航标题模式
    .backgroundColor("#AABBCB")
    .mode(NavigationMode.Auto) //导航栏的显示模式。默认值:NavigationMode.Auto自适应:基于组件宽度自适应单栏和双栏。
  }
}


/**
 * 用于测试新页面覆盖之前页面
 */
@Component
struct  ContentComponent{
  build() {
    Column(){
      Text("我会覆盖之前的页面内容")
    }.width("100%").height("100%").backgroundColor(Color.Orange)
  }
}

预览效果如下:点击后会覆盖之前的页面显示,可以通过.mode(NavigationMode.Auto)来调整显示模式

2)实现类似于之前通过tabs微信聊天页面

案例代码如下:

@Entry
@Component
struct NavigationDemo {
  @State index: number = 0;// 选项卡下标,默认为第一个

  @Builder toolbar() {// 通过builder自定义toolbar
    Row() {
      Column() {
        Image(this.index == 0 ? $r("app.media.icon_message_selected") : $r("app.media.icon_contract_normal"))
          .size({width: 25, height: 25})
        Text('消息')
          .fontSize(16)
          .fontColor(this.index == 0 ? "#2a58d0" : "#6b6b6b")
      }
      .alignItems(HorizontalAlign.Center)
      .height('100%')
      .layoutWeight(1)
      .onClick(() => {
        this.index = 0;
      })

      Column() {
        Image(this.index == 1 ? $r("app.media.icon_contract_selected") : $r("app.media.icon_contract_normal"))
          .size({width: 25, height: 25})
        Text('联系人')
          .fontSize(16)
          .fontColor(this.index == 1 ? "#2a58d0" : "#6b6b6b")
      }
      .alignItems(HorizontalAlign.Center)
      .height('100%')
      .layoutWeight(1)
      .onClick(() => {
        this.index = 1;
      })
      Column() {
        Image(this.index == 2 ? $r("app.media.icon_dynamic_selected") : $r("app.media.icon_dynamic_normal"))
          .size({width: 25, height: 25})
        Text('动态')
          .fontSize(16)
          .fontColor(this.index == 2 ? "#2a58d0" : "#6b6b6b")
      }
      .alignItems(HorizontalAlign.Center)
      .height('100%')
      .layoutWeight(1)
      .onClick(() => {
        this.index = 2;
      })
    }
    .width('100%')
    .height(45)
    .alignItems(VerticalAlign.Center)
  }

  build() {
    Navigation(){
      Text(this.index == 0 ? "消息" : this.index == 1 ? "联系人" : "动态")
        .textAlign(TextAlign.Center)
        .fontSize(30)
        .size({width: '100%', height: '100%'})
        .backgroundColor('#aabbcc')
    }
    .width("100%")
    .height("100%")
    .title("全部课程") //标题
    .menus([
      {
        value:"",//菜单文字描述
        icon:"./images/three_point.svg", //菜单的图标,必须是字符串,不能直接使用media 下的文字
        action: ()=> { //点击后触发的事件
          console.log("-------------------------search")
        }
      }
    ])
    /*.toolbarConfiguration([ //设置工具栏内容。不设置时不显示工具栏。跟tabs一致
      {value:"笔记",
        icon: $r("app.media.note"),//默认图标
        //status: ToolbarItemStatus.ACTIVE,//工具栏单个选项的状态。设置工具栏单个选项为ACTIVE态, 该选项通过点击事件可以将icon图标更新为activeIcon对应的图片资源。
        //activeIcon:$r("app.media.note_seleted"), //点击选中时的图标
        action:()=>{
          console.log("hello123");
      }},
      {value:"待办",
        icon:$r("app.media.pending"),//默认图标
        //status: ToolbarItemStatus.ACTIVE,//工具栏单个选项的状态。设置工具栏单个选项为ACTIVE态, 该选项通过点击事件可以将icon图标更新为activeIcon对应的图片资源。
        //activeIcon:$r("app.media.pending_seleted"), //点击选中时的图标
        action:()=>{
          console.log("world123");
      }}
    ])*/
    .toolbarConfiguration(this.toolbar())
    .titleMode(NavigationTitleMode.Mini) //导航标题模式

  }
}

预览效果如下:

posted @ 2024-03-21 18:38  酒剑仙*  阅读(196)  评论(0)    收藏  举报