鸿蒙 HarmonyOS 实战 -ArkUI 组件(Tabs)
- 2024-05-07 湖南
本文字数:7253 字
阅读完需:约 24 分钟
![鸿蒙HarmonyOS实战-ArkUI组件(Tabs)](https://static001.geekbang.org/infoq/55/55e967f9bca015df73bb1618c6bf4ab4.jpeg)
🚀一、Tabs
Tabs 组件是一种常见的用户界面(UI)组件,它是一个可以容纳多个选项卡的容器组件。每个选项卡通常包含一个面板和一个标签,用户可以通过点击标签来切换面板。Tabs 组件通常用于展示多个相关但又不需要同时展示的数据集合或功能集合,以提高页面的可维护性和可用性。
Tabs 组件的主要功能包括:
切换选项卡:用户可以通过点击标签来切换显示面板。
激活状态:当前选中的标签会呈现激活状态,以便用户清楚地知道他们当前所在的选项卡。
自定义选项卡内容:用户可以通过自定义选项卡内容(例如图片、文本、图标等)来增强页面的可读性和可用性。
加载延迟:如果页面需要加载大量数据或内容,Tabs 组件可以通过延迟加载未激活的面板来提升页面性能。
更多鸿蒙最新技术知识点,请关注作者博客:https://t.doruo.cn/14DjR1rEY
🔎1.基本布局
![](https://static001.geekbang.org/infoq/03/03146c104c83602f2e1a4e41b749309f.png)
Tabs 使用花括号包裹 TabContent,每一个 TabContent 对应一个 tabBar
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs() {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/50/50159ccca34a67d8e02cf353a7cc1a8a.png)
🔎2.导航位置
🦋2.1 底部导航
BarPosition.End 设置底部导航
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/43/436259c7baad5b9dbfea6c9e55263f17.png)
🦋2.2 顶部导航
BarPosition.Start 设置顶部导航
更多鸿蒙最新技术知识点,请关注作者博客:https://t.doruo.cn/14DjR1rEY
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/dc/dcae28644c70331774468188bfdc8296.png)
🦋2.3 侧边导航
实现侧边导航栏需要设置 Tabs 的属性 vertical 为 true
vertical 为 false 时,tabbar 宽度会默认撑满屏幕的宽度,需要设置 barWidth 为合适值。
vertical 为 true 时,tabbar 的高度会默认实际内容高度,需要设置 barHeight 为合适值。
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}.vertical(true)
.barWidth(100)
.barHeight(200)
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/b3/b3d68e45507573abbcdbd0da3095c615.png)
🔎3.导航效果
🦋3.1 限制导航栏的滑动切换
在某些需要进行多级分类的页面上,如同时存在底部导航栏和顶部导航栏时,因为默认情况下导航栏都支持滑动切换,所以当底部导航栏的滑动效果与顶部导航栏出现冲突时,需要限制底部导航栏的滑动,以避免给用户带来不好的体验。
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs({ barPosition: BarPosition.End }) {
TabContent(){
Column(){
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}.vertical(true)
.barWidth(100)
.barHeight(200)
}
.backgroundColor('#ff08a8f1')
.width('100%')
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}
.scrollable(false)
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/ef/efa7e0fd2c200d0c99af8bdc9e3ea228.png)
🦋3.2 固定导航栏
Tabs 的属性 barMode 是控制导航栏是否可以滚动,默认值为 Fixed
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs({ barPosition: BarPosition.End }) {
TabContent(){
Column(){
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}.vertical(true)
.barWidth(100)
.barHeight(200)
}
.backgroundColor('#ff08a8f1')
.width('100%')
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}
.scrollable(false)
.barMode(BarMode.Fixed)
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/a3/a34804dbdaacee8b775d8822ba9b6af2.png)
🦋3.3 滚动导航栏
滚动导航栏需要设置 Tabs 组件的 barMode 属性,默认情况下其值为 Fixed,表示为固定导航栏,设置为 Scrollable 即可设置为可滚动导航栏
更多鸿蒙最新技术知识点,请关注作者博客:https://t.doruo.cn/14DjR1rEY
@Entry
@Component
struct NavigationExample {
private arr: number[] = [1, 2, 3];
build() {
Column() {
Tabs({ barPosition: BarPosition.End }) {
TabContent(){
Column(){
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
Text('首页的内容').fontSize(30)
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}.vertical(true)
.barWidth(100)
.barHeight(200)
}
.backgroundColor('#ff08a8f1')
.width('100%')
}
.tabBar('首页')
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
TabContent() {
Text('推荐的内容').fontSize(30)
}
.tabBar('推荐')
TabContent() {
Text('发现的内容').fontSize(30)
}
.tabBar('发现')
TabContent() {
Text('我的内容').fontSize(30)
}
.tabBar("我的")
}
.scrollable(false)
.barMode(BarMode.Scrollable)
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/fa/fae7ecc5c157b1e846f36ed75bb854ab.png)
🔎4.自定义导航栏
自定义导航栏是指在应用开发中,开发者使用自己定制的视图代替系统自带的导航栏,以实现更加自由、灵活和符合应用风格的导航栏。自定义导航栏可以包括各种 UI 元素,例如按钮、文本、图片、标签等,以满足不同应用的需求。自定义导航栏可以帮助应用创建独特的风格和品牌形象,提高用户体验和应用的可用性。
@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
Column() {
Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
.size({ width: 25, height: 25 })
Text(title)
.fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}
TabContent() {
Column(){
Text('我的内容')
}
.width('100%')
.height('100%')
.backgroundColor('#007DFF')
}
.tabBar(this.TabBuilder('我的', 0, $r('app.media.mine_selected'), $r('app.media.mine_normal')))
![](https://static001.geekbang.org/infoq/fc/fc3d4b8a78e2633cc3817bbf0afe9a7c.png)
🔎5.切换至指定页签
要想切换特定的标签页,需要使用 TabsController。TabsController 是 Tabs 组件的控制器,它用于控制 Tabs 组件进行标签页的切换。使用 TabsController 的 changeIndex 方法,可以实现跳转到指定索引值对应的标签页内容。
@Entry
@Component
struct NavigationExample {
private tabsController : TabsController = new TabsController()
@State currentIndex:number = 0;
@Builder TabBuilder(title: string, targetIndex: number) {
Column() {
Text(title)
.fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
}
.onClick(() => {
this.currentIndex = targetIndex;
this.tabsController.changeIndex(this.currentIndex);
})
}
build() {
Column() {
Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
TabContent(){
Text('首页')
}.tabBar(this.TabBuilder('首页',0)).backgroundColor(Color.Black)
TabContent(){
Text('发现')
}.tabBar(this.TabBuilder('发现',1)).backgroundColor(Color.Blue)
TabContent(){
Text('推荐')
}.tabBar(this.TabBuilder('推荐',2)).backgroundColor(Color.Red)
TabContent(){
Text('我的')
}
.tabBar(this.TabBuilder('我的',3)).backgroundColor(Color.Pink)
}
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/3a/3a39276b264bd6fb8b720c061492cd1c.png)
🔎6.滑动切换导航栏
在不使用自定义导航栏的情况下,Tabs 组件会默认实现 tabBar 与 TabContent 的切换联动。然而,一旦使用了自定义导航栏,就需要使用 TabsController 来实现点击页签与页面内容的联动。但使用 TabsController 无法实现滑动页面时,页面内容对应页签的联动。也就是说,当用户滑动屏幕切换页面内容时,页签栏无法同步切换至对应的页签,这可能会影响用户的体验。
@Entry
@Component
struct NavigationExample {
private tabsController : TabsController = new TabsController()
@State currentIndex:number = 0;
@Builder TabBuilder(title: string, targetIndex: number) {
Column() {
Text(title)
.fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')
}
.onClick(() => {
this.currentIndex = targetIndex;
this.tabsController.changeIndex(this.currentIndex);
})
}
build() {
Column() {
Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {
TabContent(){
Text('首页')
}.tabBar(this.TabBuilder('首页',0)).backgroundColor(Color.Black)
TabContent(){
Text('发现')
}.tabBar(this.TabBuilder('发现',1)).backgroundColor(Color.Blue)
TabContent(){
Text('推荐')
}.tabBar(this.TabBuilder('推荐',2)).backgroundColor(Color.Red)
TabContent(){
Text('我的')
}
.tabBar(this.TabBuilder('我的',3)).backgroundColor(Color.Pink)
}.onChange((index) => {
this.currentIndex = index
})
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
}
![](https://static001.geekbang.org/infoq/9f/9f343b16b03f74f5dbb7abd3edf028fc.png)
🚀写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注小编,同时可以期待后续文章 ing🚀,不定期分享原创知识。
更多鸿蒙最新技术知识点,请关注作者博客:https://t.doruo.cn/14DjR1rEY
![](https://static001.geekbang.org/infoq/17/17dd6f08bf8f17a5291cd52513261457.png)
![用户头像](http://static001.geekbang.org/account/avatar/00/3a/16/1c/15a52542.jpg?x-oss-process=image/resize,w_200,h_200)
蜀道山
欢迎关注作者公众号:【 蜀道衫】 2023-12-29 加入
3年Java后端,5年Android应用开发,精通Java高并发、JVM调优、以及Android开发各种技能。现专研学习鸿蒙HarmonyOS Next操作系统
评论