Navigation组件
一、Navigation组件介绍
Navigation组件一般作为页面的根容器,包括单页面、分栏和自适应三种显示模式。同时,Navigation提供了属性,来设置页面的标题栏、工真栏、导航栏等。
Navigation组件的页面包含主页和内容页。主页由标题栏、内容区和工具栏组成,可在内容区中使用NavRouter子组件实现导航栏功能。内容页主要显示NavDestination子组件中的内容。NavRouter是配合Navigation使用的特殊子组件,默认提供点击响应处理,不需要开发者自定义点击事件逻辑,NavRouter有且仅有两个子组件,其中第二个子组件必须是NavDestination。
NavDestination是配合NavRouter使用的特殊子组件,用于显示Navigation组件的内容页。当开发者点击NavRouter组件时,会跳转到对应的NavDestination内容区。
二、接口
2.1.接口:
Navigation()
2.2.参数:
参数名 | 参数类型 | 必填 | 参数描述 |
---|---|---|---|
pathInfos | NavPathStack | 否 | 路由栈信息。 |
名称 | 枚举值 | 描述 |
---|---|---|
Push | 1 | 跳转到应用内的指定页面。 |
Replace | 2 | 用应用内的某个页面替换当前页面,并销毁被替换的页面。 |
Back | 3 | 返回到指定的页面。指定的页面不存在栈中时不响应。未传入指定的页面时返回上一页。 |
2.3.属性
支持以下属性:
名称 | 参数类型 | 描述 |
---|---|---|
title | ResourceStr10+ | CustomBuilder| NavigationCommonTitle9+ | 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+ | [Dimension, Dimension] |
导航栏最小和最大宽度(双栏模式下生效)。 默认值:最小默认值 240,最大默认值为组件宽度的40% ,且不大于 432,如果只设置一个值,则未设置的值按照默认值计算。 单位:vp 规则:优先级规则详见说明。 |
minContentWidth10+ | Dimension |
导航栏内容区最小宽度(双栏模式下生效)。 默认值:360 单位:vp 规则:优先级规则详见说明。 Auto模式断点计算:默认600vp,minNavBarWidth(240vp) + minContentWidth (360vp) |
-
仅设置navBarWidth,不支持Navigation分割线拖拽。
-
navBarWidthRange指定分割线可以拖拽范围。如果不设置值,则按照默认值处理。拖拽范围需要满足navBarWidthRange设置的范围和minContentWidth限制。
-
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) //导航标题模式 } }
预览效果如下: