OpenHarmony 应用开发之 Navigation 组件详解
- 2022 年 7 月 05 日
本文字数:9713 字
阅读完需:约 32 分钟
页面导航(Navigation)
Navigation 一般作为 Page 页面的根容器,通过属性设置来展示页面的标题、它提供了一系列属性方法来设置页面的标题栏、工具栏以及菜单栏的各种展示样式。 Navigation 除了提供了默认的展示样式属性外,它还提供了 CustomBuilder 模式来自定义展示样式,本节将介绍一下 Navigation 各属性的简单用法以及使用 CustomBuilder 实现自定义样式。
Navigation 定义介绍
interface NavigationInterface { /** * Called when the navigator view interface is used. */ (): NavigationAttribute;}
Navigation 的定义不需要传递相关参数,我们先看下 Navigation 的最简单样例:
@Entry@Componentstruct ResourceTest { @State text_string: string = "跟着坚果学习OpenHarmony应用开发";
build() { Navigation() { // Navigation只能包含一个子组件 } }}
运行结果如下图所示:
由运行结果可知,在默认情况下, Navigation 的样式是一个带有返回箭头的标题栏组成的。
Navigation 属性介绍
我们可以点开它的方法看一下,首先他也是继承了 CommonMethod,然后对其进行自定义。
declare class NavigationAttribute extends CommonMethod<NavigationAttribute> { /** * 设置导航栏的标题,当参数类型为 `string` 时,可以直接设置标题,当参数为 `CustomBuilder` 时,可以自定义标题样式。
*/ title(value: string | CustomBuilder): NavigationAttribute;
/** * Navigation subtitle
*/ subTitle(value: string): NavigationAttribute;
/** * Hide navigation bar */ hideTitleBar(value: boolean): NavigationAttribute;
/** * Hide navigation back button */ hideBackButton(value: boolean): NavigationAttribute;
/** * Navigation title mode */ titleMode(value: NavigationTitleMode): NavigationAttribute;
/** * Navigation title bar's menus */ menus(value: Array<NavigationMenuItem> | CustomBuilder): NavigationAttribute;
/** * Tool bar */ toolBar(value: object | CustomBuilder): NavigationAttribute;
/** * Hide tool bar */ hideToolBar(value: boolean): NavigationAttribute;
/** * Trigger callback when title mode change finished at free mode. */ onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void): NavigationAttribute;}
title:设置导航栏的标题,当参数类型为 string 时,可以直接设置标题,但样式不支修改;当参数为 CustomBuilder 时,可以自定义标题样式。
参数类型为
string,简单样例如下所示:
@Entry @Component struct ResourceTest { @State content: string = "跟着坚果学习OpenHarmony应用开发"; @State title: string = "这是标题"; build() { Navigation() { Text(this.content) .textAlign(TextAlign.Center) .fontSize(30) .backgroundColor(Color.Orange) .size({ width: '100%', height: '100%' }) } .size({ width: '100%', height: '100%' }) .title(this.title) // 设置title,此时不支持修改文字大小,颜色等样式 } }
样例运行结果如下图所示:
参数类型为
CustomBuilder,简单样例如下所示:
@Entry @Component struct ResourceTest { @State content: string = "跟着坚果学习OpenHarmony应用开发"; @State title: string = "这是标题"; @Builder titleWidget() {// 通过Builder自定义标题栏,可以灵活的设置标题样式 Row() { Text(this.title).textAlign(TextAlign.Center) .fontSize(20).margin({right:20}) Image($r("app.media.door_lock")).width(30) }.justifyContent(FlexAlign.Center) .width('100%') .height(30) .backgroundColor(Color.Gray) } build() { Navigation() { Text(this.content) .textAlign(TextAlign.Center) .fontSize(30) .backgroundColor(Color.Orange) .size({ width: '100%', height: '100%' }) } .size({ width: '100%', height: '100%' }) .title(this.titleWidget) // 设置title,此时不支持修改文字大小,颜色等样式 } }
样例运行结果如下图所示(为了观察的更细致,我只截了上半部分):
subTitle:设置页面的副标题,简单样例如下所示:
@Entry@Componentstruct ResourceTest { @State content: string = "跟着坚果学习OpenHarmony应用开发"; @State title: string = "这是标题"; @State sub_title: string = "这是副标题"; @Builder titleWidget() {// 通过Builder自定义标题栏,可以灵活的设置标题样式 Row() {
Text(this.title).textAlign(TextAlign.Center) .fontSize(20).margin({right:20}) Image($r("app.media.door_lock")).width(30) }.justifyContent(FlexAlign.Center) .width('100%') .height(30) .backgroundColor(Color.Gray) }
build() { Navigation() { Text(this.content) .textAlign(TextAlign.Center) .fontSize(30) .backgroundColor(Color.Orange) .size({ width: '100%', height: '100%' }) } .size({ width: '100%', height: '100%' }) .title(this.titleWidget) // 设置title,此时不支持修改文字大小,颜色等样式 .subTitle(this.sub_title) }}
样例运行结果如下图所示:
hideBackButton:是否隐藏返回按钮,默认情况下不隐藏,简单样例如下所示:
@Entry@Componentstruct ResourceTest { @State content: string = "跟着坚果学习OpenHarmony应用开发"; @State title: string = "这是标题"; @State sub_title: string = "这是副标题"; @Builder titleWidget() {// 通过Builder自定义标题栏,可以灵活的设置标题样式 Row() {
Text(this.title).textAlign(TextAlign.Center) .fontSize(20).margin({right:20}) Image($r("app.media.door_lock")).width(30) }.justifyContent(FlexAlign.Center) .width('100%') .height(30) .backgroundColor(Color.Gray) }
build() { Navigation() { Text(this.content) .textAlign(TextAlign.Center) .fontSize(30) .backgroundColor(Color.Orange) .size({ width: '100%', height: '100%' }) } .size({ width: '100%', height: '100%' }) .title(this.titleWidget) // 设置title,此时不支持修改文字大小,颜色等样式 .subTitle(this.sub_title)// 设置subTitle,此时不支持修改文字大小,颜色等样式 .hideBackButton(true) }}
样例运行结果如下图所示:
toolBar:设置工具栏,当参数类型为 object 时,可以直接设置工具栏选项,但样式不支修改;当参数为 CustomBuilder 时,可以自定义标题栏。
当参数为
object类型时,参数需要按照如下格式定义:value:工具栏单个选项的显示文本。
icon:工具栏单个选项的图标资源路径。
action:当前选项被选中时的事件回调。
简单样例如下所示:
@Entry @Component struct ResourceTest { @State content: string = "跟着坚果学习OpenHarmony应用开发"; @State title: string = "这是标题"; @State sub_title: string = "这是副标题"; @Builder titleWidget() { // 通过Builder自定义标题栏,可以灵活的设置标题样式 Row() { Text(this.title).textAlign(TextAlign.Center) .fontSize(20).margin({ right: 20 }) Image($r("app.media.door_lock")).width(30) }.justifyContent(FlexAlign.Center) .width('100%') .height(30) .backgroundColor(Color.Gray) } build() { Navigation() { Text(this.content) .textAlign(TextAlign.Center) .fontSize(30) .backgroundColor(Color.Orange) .size({ width: '100%', height: '100%' }) } .size({ width: '100%', height: '100%' }) .title(this.titleWidget) // 设置title,此时不支持修改文字大小,颜色等样式 .subTitle(this.sub_title) // 设置subTitle,此时不支持修改文字大小,颜色等样式 .hideBackButton(true) .toolBar({ items: [ // toolBar接收一个数组 { value: "消息", // 文本 action: () => { // 事件 console.log("点击了消息") } }, { value: "动态", action: () => { console.log("点击了首页") } }, { value: "我的", action: () => { console.log("点击了首页") } } ] }) } }
样例运行结果如下图所示:
当参数为
CustomBuilder类型时,可以自定义样式,简单样例如下所示:
@Entry @Component struct ComponentTest { @State index: number = 0;// 选项卡下标,默认为第一个 @Builder toolbarWidget() {// 通过builder自定义toolbar Row() { Column() { Image(this.index == 0 ? 'common/images/tab-home-Select.png' : 'common/images/tab-home-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('主页') .fontSize(16) .fontColor(this.index == 0 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 0; }) Column() { Image(this.index == 1 ? 'common/images/tab-my-Select.png' : 'common/images/tab-my-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('汪汪') .fontSize(16) .fontColor(this.index == 1 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 1; }) Column() { Image(this.index == 2 ? 'common/images/tab-news-Select.png' : 'common/images/tab-news-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('消息') .fontSize(16) .fontColor(this.index == 2 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 2; }) } .width('100%') .height(60) } build() { Navigation() { Text(this.index == 0 ? "主页" : this.index == 1 ? "汪汪" : "消息") .textAlign(TextAlign.Center) .fontSize(30) .size({width: '100%', height: '100%'}) .backgroundColor(Color.Orange) } .size({width: '100%', height: '100%'}) .title("跟着坚果学OpenHarmony") .toolBar(this.toolbarWidget()) } }
样例运行结果如下图所示:
hideTitleBar、hideToolBar:设置是否显示或者隐藏标题栏、工具栏,简单样例如下所示:
@Entry @Component struct ComponentTest {
@State index: number = 0;// 选项卡下标,默认为第一个 @State hideToolBar: boolean = false; @State hideTitleBar: boolean = false;
@Builder toolbarWidget() {// 通过builder自定义toolbar Row() { Column() { Image(this.index == 0 ? 'common/images/tab-home-Select.png' : 'common/images/tab-home-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('主页') .fontSize(16) .fontColor(this.index == 0 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 0; })
Column() { Image(this.index == 1 ? 'common/images/tab-my-Select.png' : 'common/images/tab-my-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('汪汪') .fontSize(16) .fontColor(this.index == 1 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 1; })
Column() { Image(this.index == 2 ? 'common/images/tab-news-Select.png' : 'common/images/tab-news-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('消息') .fontSize(16) .fontColor(this.index == 2 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 2; }) } .width('100%') .height(60) }
build() { Navigation() { Column({space: 20}) { Text(this.index == 0 ? "主页" : this.index == 1 ? "汪汪" : "消息") .textAlign(TextAlign.Center) .fontSize(30)
Button(this.hideTitleBar ? "显示TitleBar" : "隐藏TitleBar") .onClick(() => { this.hideTitleBar = !this.hideTitleBar; }).backgroundColor(Color.Green)
Button(this.hideToolBar ? "显示ToolBar" : "隐藏ToolBar") .onClick(() => { this.hideToolBar = !this.hideToolBar; }).backgroundColor(Color.Red) } .backgroundColor(Color.Orange).justifyContent(FlexAlign.SpaceAround).alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center) .size({width: '100%', height: '100%'}) } .size({width: '100%', height: '100%'}) .title("跟着坚果学OpenHarmony") .toolBar(this.toolbarWidget()) .hideToolBar(this.hideToolBar) .hideTitleBar(this.hideTitleBar) }}
样例运行结果如下图所示:
menus:设置标题栏右上角的菜单项,当参数为 CustomBuilder 时可以自定义菜单项。
当参数为
NavigationMenuItem数组时,参数说明如下:value:菜单项的显示文本。
icon:菜单项的显示图标路径。
action:点击菜单项的事件回调。
简单样例如下所示:
@Entry @Component struct ComponentTest { @State index: number = 0;// 选项卡下标,默认为第一个 @State hideToolBar: boolean = false; @State hideTitleBar: boolean = false; @Builder toolbarWidget() {// 通过builder自定义toolbar Row() { Column() { Image(this.index == 0 ? 'common/images/tab-home-Select.png' : 'common/images/tab-home-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('主页') .fontSize(16) .fontColor(this.index == 0 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 0; }) Column() { Image(this.index == 1 ? 'common/images/tab-my-Select.png' : 'common/images/tab-my-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('汪汪') .fontSize(16) .fontColor(this.index == 1 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 1; }) Column() { Image(this.index == 2 ? 'common/images/tab-news-Select.png' : 'common/images/tab-news-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('消息') .fontSize(16) .fontColor(this.index == 2 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 2; }) } .width('100%') .height(60) } build() { Navigation() { Column({space: 20}) { Text(this.index == 0 ? "主页" : this.index == 1 ? "汪汪" : "消息") .textAlign(TextAlign.Center) .fontSize(30) Button(this.hideTitleBar ? "显示TitleBar" : "隐藏TitleBar") .onClick(() => { this.hideTitleBar = !this.hideTitleBar; }).backgroundColor(Color.Green) Button(this.hideToolBar ? "显示ToolBar" : "隐藏ToolBar") .onClick(() => { this.hideToolBar = !this.hideToolBar; }).backgroundColor(Color.Red) } .backgroundColor(Color.Orange).justifyContent(FlexAlign.SpaceAround).alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center) .size({width: '100%', height: '100%'}) } .size({width: '100%', height: '100%'}) .title("跟着坚果学OpenHarmony") .toolBar(this.toolbarWidget()) .hideToolBar(this.hideToolBar) .hideTitleBar(this.hideTitleBar) .menus([ { value: "关门", icon: 'common/images/door_lock.svg', action: () => { } }, { value: "开们", icon: 'common/images/door_unlock.svg', action: () => { } } ]) } }
样例运行结果如下图所示:
titleMode: 页面标题栏显示模式,默认为 NavigationTitleMode.Free
NavigationTitleMode 枚举说明
Navigation 事件介绍
declare class NavigationAttribute extends CommonMethod<NavigationAttribute> { onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void): NavigationAttribute;}
onTitleModeChange:当
titleMode为 NavigationTitleMode.Free 时,随着可滚动组件的滑动标题栏模式发生变化时触发此回调。
@Entry @Component struct ComponentTest {
@State index: number = 0;// 选项卡下标,默认为第一个 @State hideToolBar: boolean = false; @State hideTitleBar: boolean = false;
@Builder toolbarWidget() {// 通过builder自定义toolbar Row() { Column() { Image(this.index == 0 ? 'common/images/tab-home-Select.png' : 'common/images/tab-home-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('主页') .fontSize(16) .fontColor(this.index == 0 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 0; })
Column() { Image(this.index == 1 ? 'common/images/tab-my-Select.png' : 'common/images/tab-my-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('汪汪') .fontSize(16) .fontColor(this.index == 1 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 1; })
Column() { Image(this.index == 2 ? 'common/images/tab-news-Select.png' : 'common/images/tab-news-Unchecked.png') .size({width: 25, height: 25}).margin({bottom:4,top:4}) Text('消息') .fontSize(16) .fontColor(this.index == 2 ? Color.Orange : null) } .alignItems(HorizontalAlign.Center) .height('100%') .layoutWeight(1) .onClick(() => { this.index = 2; }) } .width('100%') .height(60) }
build() { Navigation() { Column({space: 20}) { Text(this.index == 0 ? "主页" : this.index == 1 ? "汪汪" : "消息") .textAlign(TextAlign.Center) .fontSize(30)
Button(this.hideTitleBar ? "显示TitleBar" : "隐藏TitleBar") .onClick(() => { this.hideTitleBar = !this.hideTitleBar; }).backgroundColor(Color.Green)
Button(this.hideToolBar ? "显示ToolBar" : "隐藏ToolBar") .onClick(() => { this.hideToolBar = !this.hideToolBar; }).backgroundColor(Color.Red) } .backgroundColor(Color.Orange).justifyContent(FlexAlign.SpaceAround).alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center) .size({width: '100%', height: '100%'}) } .size({width: '100%', height: '100%'}) .title("跟着坚果学OpenHarmony") .toolBar(this.toolbarWidget()) .hideToolBar(this.hideToolBar) .hideTitleBar(this.hideTitleBar) .menus([ { value: "关门", icon: 'common/images/door_lock.svg', action: () => {
} }, { value: "开们", icon: 'common/images/door_unlock.svg', action: () => {
} } ]).onTitleModeChange((titleModel: NavigationTitleMode) => { console.log('titleMode') }) .titleMode(NavigationTitleMode.Free) }}
效果
小结
大家了解完这个组件,是不是对 UI 开发,有了更加直观的认识,在我看来,只要大家学会了这个组件的使用,那么我相信,大部分的 UI 都可以实现了。
了 Navigation 组件的基本使用,读者掌握了该组件的使用后可以开发更丰富的 UI 界面了。
参考
[Navigation](ying y
版权声明: 本文为 InfoQ 作者【坚果】的原创文章。
原文链接:【http://xie.infoq.cn/article/c740c2da2c2cccd7dd36246b8】。文章转载请联系作者。
坚果
此间若无火炬,我便是唯一的光 2020.10.25 加入
公众号:“大前端之旅”,华为云享专家,InfoQ签约作者,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。










评论