今天自己学习了鸿蒙开发中的Tabs组件,本人将知识点和用法总结了下。
我们在日常APP使用中时常会用到导航栏来切换不同的内容频道,来浏览想要的内容。 比如bilibili的导航栏
这样的内容就是通过Tabs来实现的,当然导航栏也可以调整位置。如侧边导航栏,底部导航栏等,下面是三种导航栏的样式:
一、导航栏的基本用法
Tabs是一个顶级容器,Tabs的子组件里面只能存在TabContent组件,每一个TabContent组件都是一个导航选项卡。在TabContent中只能有一个根组件如Row、Column等。在TabContent里面展示的是页面的内容,而导航栏中选项卡的内容则是由属性tabBar来设置。
Tabs的语法:
// 顶级容器组件
// Tabs(){
// 只能放TabContent
// TabContent(){
// 内容 只能有一个根组件
// }
// .tabBar(导航栏显示的内容)
// }
我们使用代码生成一个简单的导航页面:
@Entry
@Component
struct Page06_Tabs {
build() {
Tabs() {
// 内容
TabContent() {
Text('首页的内容')
.fontSize(30)
}
// tabBar
.tabBar('首页')
TabContent() {
Text('推荐的内容')
.fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容')
.fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容')
.fontSize(30)
}
.tabBar("我的")
}
}
}
二、导航栏的属性
我们可以通过下面的属性来调整Tabs的样式:
- vertical 属性即可调整导航为 水平 或 垂直
- barPosition 即可调整导航位置为 开头 或 结尾
- scrollable 即可调整是否允许 页面滑动切换
- animationDuration 设置动画时间 毫秒
- barHeight 设置tabBar的高度
- divider 设置tabBar和tebContent的分割线
这个时候如果我们设置了较多的导航栏则会发现导航栏的内容都挤到一块了,这个问题我们只需要为导航栏设置滚动效果即可。通过Tabs组件的barMode属性可以调整固定导航栏或者滚动导航栏。不主动设置导航栏的话默认值为固定导航栏
Tabs(){
// 内容
}
.barMode(BarMode.Scrollable)// 设置为滚动导航栏
// .barMode(BarMode.Fixed) 设置为固定导航栏
三、自定义导航栏
如果导航栏在底部的话,通常是图片和文字的样式,或者是特殊的图标。像bilibili的底部导航栏,就是由图片和文字组成的。
这个时候就需要自定义导航栏来设置外观了。使用@Builder将自定义的导航栏结构抽离出来,然后在tabBar处调用。
Tabs() {
TabContent() {
// 内容
}
//调用抽离的结构
.tabBar(this.tabBarBuilder())
}
//使用Builder来构造自己的样式。
@Builder
tabBarBuilder() {
// 自定义的Tabbar结构
}
四、自定义导航栏的高亮效果
导航栏默认是自带高亮效果的,但是当我们使用了自定义导航栏后高亮效果会消失,而我们则需要自己设置高亮效果。做法为:我们需要知道用户所在当前页面,然后与导航栏对应,为导航栏设置高亮的样式。以下是高亮效果的详细步骤。
1.定义一个状态变量,用来存储页面的下标。在导航栏中每个页面有一个下标用来表示当前的页面,所以我们需要获取下标来做判断,判断用户当前在哪个页面。
@State heightLightIndex: number = 0
2.使用Tabs组件的事件来获取用户在当前的哪个页面。获取到页面的下标之后,给状态变量赋值用来进行后面的判断。
(1)Tab页签切换事件:在用户将标签切换之后触发事件。
//index为页面的下标,将下标赋值给状态变量。
.onChange((index) => {
this.heightLightIndex = index
})
(2)Tab页签点击事件:在用户点击标签之后会触发的事件。
//index为页面的下标,将下标赋值给状态变量
.onTabBarClick((index) => {
this.heightLightIndex = index
})
3.将页面的下标与导航的下标做判断,如果相等则表示当前导航项就是用户在的页面,需要进行高亮显示。
.tabBar(this.tabBarBuilder(item, index))
//内容
@Builder tabBarBuilder(item: TabItems, index: number) { Column() { Image($r(item.imgUrl)) .width(30) // 4. 判断下标是否一致,一致则显示高亮,否则不高亮 .fillColor(this.heightLightIndex === index ? '#f40' : '') Text(item.text) .fontColor(this.heightLightIndex === index ? '#f40' : '') } }
这样,就实现了自定义导航的 高亮效果了。需要注意的是,Tab页签点击事件,只有点击才会触发,如果用户滑动切换页面是不会触发此事件的,使用时需要注意这一点。
附上完整代码:
interface TabItems { imgUrl: string text: string } @Entry @Component struct Page09_Tabs_CustomTabBar { @State tabItem: TabItems[] = [ { imgUrl: '图片地址', text: '购物车' }, { imgUrl: '图片地址', text: '我的' } ] //1. 定义状态变量 用来存储页面的下标 @State heightLightIndex: number = 0 //高亮效果的核心: 页面的下标和导航的下标是否一致。 build() { Tabs() { ForEach(this.tabItem, (item: TabItems, index: number) => { TabContent() { Text(item.text) } // 3.index 下标传递到builder函数中,index用来做导航下标。 .tabBar(this.tabBarBuilder(item, index)) }) } .barPosition(BarPosition.End) //页面切换执行此事件 .onChange((index) => { // 2. 在事件中存储下标 this.heightLightIndex = index }) } @Builder tabBarBuilder(item: TabItems, index: number) { Column() { Image($r(item.imgUrl)) .width(30) // 4. 判断下标是否一致,一致则显示高亮,否则不高亮 .fillColor(this.heightLightIndex === index ? '#f40' : '') Text(item.text) .fontColor(this.heightLightIndex === index ? '#f40' : '') } } }
图片请自己设置。