鸿蒙应用开发从入门到入行 - 篇8:Tabs选项卡页签视图切换
鸿蒙应用开发从入门到入行
第八天 - Tabs选项卡
导读:在本篇文章里,您将掌握使用Tabs选项卡做栏目分类,这是未来应用开发中极为常用的组件
首先说一声抱歉,比较忙很久没更新了。但放心吧,目前该忙的事已经忙完,后面会恢复更新频率。以及后续有计划出一套免费视频教程,敬请期待!
本篇文章所用素材下载: media.zip
Tabs介绍
你是否经常在移动端应用里见到如下菜单分类,例如下面两图
像这样的不管是在上,还是在下的菜单分栏功能,在HarmonyOS应用开发中都是可以使用Tabs组件实现
每当某个Tabs里的菜单切换后,页面内容也会跟着改变,如下图
也即:Tabs组件可以在一个页面内快速实现视图内容的切换
具体怎样使用呢?我们接着往下看
Tabs - 组件基本使用
- 首先,Tabs里面只能放
TabContent子组件(放其他组件会报错),有多少个TabContent,就意味着有多少个切换视图。
如上图所示,这段代码里
Tabs放了三个TabContent,因此有三个视图进行切换。但此时仅能实现左滑才能切换,根本没有显示出“导航栏”,所以一般情况下还会给TabContent设置tabBar属性,用来设置对应的导航栏如下代码,给每个TabContent都设置了tabBar属性
@Entry
@Component
struct Index {
build() {
Tabs() {
TabContent() {
Text('1')
}.tabBar('首页') TabContent() {
Text('2')
}.tabBar('联系人') TabContent() {
Text('3')
}.tabBar('我的')
}
}
}此时效果如下
小结:
- Tabs里只能放TabContent
- TabContent有多少个就意味着有多少个视图切换
- TabContent配合tabBar属性,即可设置导航栏标题,tabBar传入字符串,字符串是什么,标题即为什么
修改导航栏位置到底部
默认情况下,导航栏在页面上方,如果想把导航栏设置到页面底部显示,可以通过给
Tabs传入参数barPosition来实现代码如下:
Tabs({ barPosition: BarPosition.End }) { // .... 省略里面的TabContent代码
}此时界面效果如下图
如上代码所示:barPosition参数,需要传入BarPosition的枚举,这个枚举仅有两个值:Start与End,默认即为Start,代表在顶部,设置为End即为底部
修改导航栏位置到侧边
那么是不是只有顶部、底部两种位置呢?其实不然,还可以设置左侧或右侧,这里需要用到Tabs的一个属性,即为:
vertical这个属性代表:是否垂直摆放导航栏,那换句话说即为是否竖着放(也即侧边放),默认为false即水平摆放。
我们试着把这个属性改为true,如下代码
Tabs({ barPosition: BarPosition.Start }) {
// 省略里面的TabContent代码
}
.vertical(true)
.barWidth(80)
.barBackgroundColor('#f00')效果如下图
代码解释:
- 因为vertical属性设置为true,必然是在侧边摆放导航栏,但为什么是左边呢?因为Tabs的
barPosition参数设置为Start(默认值),即为在左侧,所以如果barPosition设置为BarPosition.End,即为在右侧。 - barWidth是设置导航条的宽度(侧边方向是设置宽度)或高度(上下方向是设置高度)
- barBackgroundColor是设置导航条背景颜色,这里加背景色主要是为了让大家能看到我们设置的宽度生效了
- 因为vertical属性设置为true,必然是在侧边摆放导航栏,但为什么是左边呢?因为Tabs的
小结:
- 如果Tabs不设置vertical或者vertical设置为false,导航栏方向都是上下摆放,至于是上还是下跟barPosition有关,Start为上,End为下
- 如果Tabs设置了vertical为true,导航栏方向都是侧边摆放,至于是左还是右跟barPosition有关,Start为左,End为右
Tabs嵌套使用
很多时候我们的App应用场景其实需要顶部、底部都有导航栏,即整个App分为“首页”、“发现”、“推荐” 、“我的”四个部分,但是在“首页”里,又分为:关注、视频、游戏、数码、科技四个板块,如下图所示
这时候就需要嵌套导航栏(在首页这个视图里再套一个Tabs),代码如下
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
// 在首页这个视图里,又分为关注、视频、游戏、数码、科技四个切换分类
Tabs() {
TabContent() {
Text('关注的内容')
}.tabBar('关注') TabContent() {
Text('视频的内容')
}.tabBar('视频') TabContent() {
Text('游戏的内容')
}.tabBar('游戏') TabContent() {
Text('数码的内容')
}.tabBar('数码') TabContent() {
Text('科技的内容')
}.tabBar('科技')
}
}.tabBar('首页') TabContent() {
Text('发现的内容')
}.tabBar('发现') TabContent() {
Text('推荐的内容')
}.tabBar('推荐') TabContent() {
Text('我的内容')
}.tabBar('我的')
}
限制导航栏滚动
默认情况下所有的
Tabs的导航都具备滚动的功能,但是当我们使用Tabs嵌套时,如上面的场景,会发现底部的导航栏有滚动,首页里嵌套的导航栏也有滚动。为了避免他们冲突,一般我们会让底部的大导航栏禁止滚动。如何禁止滚动呢?
- 使用
scrollable属性,设置为false即可
- 使用
例
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
// 在首页这个视图里,又分为关注、视频、游戏、数码、科技四个切换分类
Tabs() {
// 省略这个嵌套的代码
}
}.tabBar('首页') TabContent() {
Text('发现的内容')
}.tabBar('发现') TabContent() {
Text('推荐的内容')
}.tabBar('推荐') TabContent() {
Text('我的内容')
}.tabBar('我的')
}
.scrollable(false)
自定义导航栏
我们很多应用的底部导航栏,其实一般除了标题文字外,还会附带图标,例如下图
这时候需要我们使用
@Builder装饰器自定义导航栏的布局后,再传递给tabBar如下代码
tabBuilder(title: string, icon: ResourceStr) {
Column({ space: 2 }) {
Image(icon)
.width(30)
Text(title)
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}- 这个Builder声明一个垂直布局的UI,上为图标,下为文字(标题),但此时这个Builder跟每个tabBar还没有任何关联,因此需要做调用绑定
代码如下
Tabs({ barPosition: BarPosition.End }) {
TabContent() {
// ...
}.tabBar(this.tabBuilder('首页', $r('app.media.ic_public_home'))) TabContent() {
// ...
}.tabBar(this.tabBuilder('信息', $r('app.media.ic_public_comments'))) TabContent() {
// ...
}.tabBar(this.tabBuilder('相册', $r('app.media.ic_public_albums'))) TabContent() {
// ...
}.tabBar(this.tabBuilder('我的', $r('app.media.ic_public_contacts')))
}此时得到效果如下图
我们会发现,不管点击哪一个,都不会有高亮效果。这是因为使用自定义导航栏后,需要自行在Builder里根据当前选中下标来判断显示不同的图标和颜色
综上所述,我们应该先声明一个状态变量,记录当前选中的索引
@State currentIndex: number = 0 // 默认为0,代表默认让第一个导航高亮修改Builder,代码如下
@Builder
tabBuilder(title: string, icon: ResourceStr, selectIcon: ResourceStr, index: number) {
Column({ space: 2 }) {
Image(this.currentIndex === index ? selectIcon : icon)
.width(30)
.fillColor(this.currentIndex === index ? '#0094ff' : '#000')
Text(title)
.fontColor(this.currentIndex === index ? '#0094ff' : '#000')
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}代码解释:
- 首先参数上新增了selectIcon与index,分别代表选中时要显示的图片,以及当前的tabBar自身索引
- 代码内根据我们记录的导航索引,与传入的当前tabBar自身索引做比较。相等就意味着当前tabBar被选中,所以让其使用选中的图片,以及设置选中的颜色。否则用默认的图片与颜色
效果如下
切换指定页签
此时我们发现,之前在不使用自定义导航栏时,默认的Tabs会实现切换逻辑,也即点谁谁高亮。但使用自定义导航栏后,发现点击导航栏没有切换高亮效果。
原因:自定义导航栏是根据我们的自定义Builder来决定显示状态的,如果需要高亮随之改变,就需要把我们声明的记录索引的状态变量进行修改,也即上面声明的
currentIndex。此时因为currentIndex一直是0,所以一直是第一个首页高亮。因此,我们需要页签改变时让currentIndex的值也跟着改变这是需要用到
Tabs提供的onChange事件,监听索引变化,并将当前切换后的索引值赋值给currentIndex,代码如下Tabs({ barPosition: BarPosition.End }) {
// 省略中间代码
}
.onChange(index => {
this.currentIndex = index
})以上利用
onChange可以实现以外,其实在Next加入$$双向绑定后也能实现,做法是,只要将currentIndex与Tabs的index参数做双向绑定即可实现,代码如下Tabs({ barPosition: BarPosition.End, index: $$this.currentIndex }) {
// 省略里面内容
}使用双向绑定还有个好处是:如果将来需要用代码改变页签,只需要改
currentIndex的值即可,例如:this.currentIndex = 2即会切换到页签索引为2的导航
总结
今日主要讲解了Tabs的使用,Tabs是一种视图切换的组件。
默认情况下,Tabs是在顶部显示,如果要改位置可以通过barPosition参数来修改
如果需要展示在侧边,可以通过 vertical 属性设置为true来实现
如果需要带图带标题的自定义导航栏,可以用@Builder进行封装并传入tabBar
课后练习
- 判断题
- 当设置vertical为true时,导航栏在右侧显示
- 当Tabs的barPosition为End,vertical为false时,导航栏在右侧显示
- 简单题
- 请回答,直接设置Tabs的vertical为true,导航栏在哪显示?
预告:下一篇内容
- 下一篇将做个鸿蒙官网的经典案例:新闻数据,即本页一开始的图如下,敬请期待
鸿蒙应用开发从入门到入行 - 篇8:Tabs选项卡页签视图切换的更多相关文章
- Python Web自动化测试入门与实战,从入门到入行
Python Web自动化测试入门与实战 购买地址 · 京东:https://item.jd.com/69239480564.html 天猫:https://detail.tmall.com/it ...
- JavaScript开发心得--如何传递某行数据给下一页
1, 应用场景 在某个html页面显示一批数据,如20个用户的名称.年龄等,每行都要一个编辑按钮,点击编辑后,将此行数据带入某个专门的编辑页进行显示,修改后保存. 问题是 点击编辑按钮后,如何得知要编 ...
- LARK BOARD开发板入门学习-第2篇
1. 本次主要研究下HDMI接口,使用芯片是CH7033,这个芯片可以接VGA和HDMI两种接口,和FPGA的接口是地址数据总线 2. 值得注意的地方,下图的D1,双二极管BAT54S在电路中一般用于 ...
- 「Android 开发」入门笔记
「Android 开发」入门笔记(界面编程篇) ------每日摘要------ DAY-1: 学习笔记: Android应用结构分析 界面编程与视图(View)组件 布局管理器 问题整理: Andr ...
- 浅谈入行Qt桌面端开发程序员-从毕业到上岗(1):当我们说到桌面端开发时,我们在谈论什么?
谈谈我自己 大家好,我是轩先生,是一个刚入行的Qt桌面端开发程序员.我的本科是双非一本的数学专业,22年毕业,只是部分课程与计算机之间有所交叉,其实在我毕业的时候并没有想过会成为一名程序员,也没有想过 ...
- PHP开发入行真功夫 三扬科技
前言与目录 PHP开发入行真功夫 前言 PHP开发入行真功夫 目录 第2章 基本语法 2.1.1 判断闰年程序 2.1.2 我们现在能做的…… 2.2.1 PHP的语言概貌 2.2.2 为我们的程 ...
- 《开发专家 Visual C 开发入行真功夫》笔记
智能感知的功能,输入 is 后,同时按下Alt + →这两个键就出现了供选择变量.方法.宏等的列表,继续输入 in 后,isInit就出来了. stdafx.h预编译头文件,.h应用程序主头文件,do ...
- 最全华为鸿蒙 HarmonyOS 开发资料汇总
开发 本示例基于 OpenHarmony 下的 JavaScript UI 框架,进行项目目录解读,JS FA.常用和自定义组件.用户交互.JS 动画的实现,通过本示例可以基本了解和学习到 JavaS ...
- [Intel Edison开发板] 03、Edison开发IDE入门及跑官方提供的DEMO
一.启动Eclipse爱迪生开发板IDE eclipse开发环境在iss-iot-win_03-14-16中,但是一定每次都是点bat脚本启动,否则就会少东西(windows->preferen ...
- iOS 非ARC基本内存管理系列 -手把手教你ARC——iOS/Mac开发ARC入门和使用(转)
手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objective-c 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流 ...
随机推荐
- 暑假集训PVZ提高模拟9
没关 exe 让这货挂了一天 UPD:又挂了一晚上,现在被我正义制裁了 A.大众点评 交互红题啊,交互会写,但是忘记判 \(n=1\) 了 这个题交互库函数实现起来还是挺简单的,我 Windows 不 ...
- Kubernetes集群安装(十三)
为了根据最新的集群特性,我们这里安装目前最新的版本 v1.19.3,如果你是在生产环境使用,建议使用上一个版本中最大的修正版本,比如 v1.15.5,由于 v1.16 版本之后和之前的版本有很大变化, ...
- 阿里云Centos7修改MariaDB数据库连接时间,解决连接mysql报Too many connection的问题
在测项目的时候突然发现数据库连接不上了,提示Too many connection. 产生问题的原因是MySQL的Sleep进程占用了大量的连接,当时是重启mysql解决的这个问题!后来又配置了连接池 ...
- 云原生爱好者周刊:client-go 示例大全
开源项目推荐 Kubernetes client-go examples 本仓库提供了非常详尽的 client-go 使用案例,非常适合 client-go 初学者. TripleCross Trip ...
- 会话层技术-session
会话层技术-session session技术拿下! 一.先整理学习过程中的几个疑惑 cookie和session分别都是怎么创建的? 首先cookie是一个类,它需要java后端开发人员手动创建. ...
- JS 通过年份获取月,季度,半年度,年度
原文请关注公众号 "酒酒酒酒",关注公众号 回复 "JS 通过年份获取月,季度,半年度,年度" 可获取源代码 功能描述: 实例化一个函数,给函数内传递不同的 ...
- Web开发核心
文章目录 1.http协议简介 2.http协议特性 3.http请求和响应协议 4.最简单的Web程序 5.基于flask搭建web⽹站 6.浏览器开发者⼯具(重点) 1.http协议简介 HTTP ...
- Oracle HR样例数据库建立
在视频的学习过程中,老师用到了HR样例数据库,但是我发现我的样例数据库中没有HR样例数据库,可能是在安装的时候漏掉了哪个环节,所以只能补救一下 如何判断自己是否有HR样例数据库呢?操作代码如下所示 第 ...
- 基于Hadoop实现的对历年四级单词的词频分析(入门级Hadoop项目)
前情提要:飞物作者屡次四级考试未能通过,进而恼羞成怒,制作了基于Hadoop实现的对历年四级单词的词频分析项目,希望督促自己尽快通过四级(然而并没有什么卵用) 项目需求:Pycharm.IDEA.Li ...
- 全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现
全网最适合入门的面向对象编程教程:58 Python 字符串与序列化-序列化 Web 对象的定义与实现 摘要: 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML\YAM ...