HarmonyOS NEXT 应用开发实战(三、ArkUI页面底部导航TabBar的实现)

在开发HarmonyOS NEXT应用时,TabBar是用户界面设计中不可或缺的一部分。本文将通过代码示例,带领大家一同实现一个常用的TabBar,涵盖三个主要的内容页:首页、知乎日报和我的页面。以模仿知乎日报的项目为背景驱动,设定一个小目标,最终实现知乎日报app项目。

1. 项目结构

在我们的代码中,首先需要导入需要使用的页面组件:

import Home from "../pages/home/Home"
import ZhiHu from "../pages/zhihu/Zhihu"
import Mine from "../pages/mine/Mine"

这三条语句确保我们可以在TabBar中使用这些页面,分别是首页,知乎日报页和个人中心页。

关于Tabs组件的官方文档:文档中心-Tabs导航组件 

2. 代码实现

接下来,我们将实现一个名为Index的组件,这是整个TabBar的核心。在此组件中,我们定义了三个主要功能:

  • 页面显示的生命周期管理
  • TabBar的构建与展示
  • 自定义Tab项样式

2.1 页面生命周期管理

我们定义了一些生命周期函数,帮助我们在页面显示和隐藏时输出相应的信息:

@Entry
@Component
struct Index {@State currentIndex: number = 0private controller: TabsController = new TabsController()onPageShow() {console.info('Index onPageShow');}onPageHide() {console.info('Index onPageHide');}onBackPress() {console.info('Index onPageBackPress');}

currentIndex用于跟踪当前选中的Tab项,而controller则用于控制Tab的切换。

2.2 构建TabBar

在组件的build方法中,我们使用Tabs组件来创建TabBar,添加每个Tab项的内容和样式配置:

build() {Column() {Tabs({barPosition: BarPosition.End,controller: this.controller}) {TabContent() {Home()}.tabBar(this.TabBuilder('首页', 0, $r('app.media.icon_sort'), $r('app.media.icon_sort_default')))TabContent() {ZhiHu()}.tabBar(this.TabBuilder('日报', 1, $r('app.media.search_select'), $r('app.media.search_default')))TabContent() {Mine()}.tabBar(this.TabBuilder('我的', 2, $r('app.media.user_selected'), $r('app.media.user')))}.scrollable(false) // 禁止滑动切换}.width('100%').height('100%')
}

这里使用了TabContent来表示每个页面的具体内容,并通过tabBar来定义每个Tab的样式和功能。

每一个TabContent对应的内容需要有一个页签,可以通过TabContent的tabBar属性进行配置。在如下TabContent组件上设置属性tabBar,可以设置其对应页签中的内容,tabBar作为内容的页签。

设置多个内容时,需在Tabs内按照顺序放置。

导航栏位置使用Tabs的参数barPosition进行设置,默认情况下,导航栏位于顶部,参数默认值为Start。设置为底部导航需要在Tabs传递参数,设置barPosition为End。

对应的图片资源,需放置在entry\src\main\resources\base\media目录中。这里发现个问题,图片只能放在这,好像里面不能再建子文件夹目录了,也就是说图片资源混在一起,这点儿有点儿不太好。

2.3 自定义Tab项样式

接下来,我们自定义了一个名为TabBuilder的方法,以便我们可以灵活地构建每个Tab的样式:

@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 ? '#28bff1' : '#8a8a8a')}.width('100%').height(50).justifyContent(FlexAlign.Center).onClick(() => {this.currentIndex = targetIndexthis.controller.changeIndex(this.currentIndex)})
}

这个构建器根据当前选中的Tab来设置图标和文字颜色,并在点击时更新currentIndex和Tab的显示状态。

在page目录下新建文件夹home,mine和zhihu分别用来存放对应的tab页的内容。这样便于清晰的管理各个页面,且不至于把所有内容都放到一个Index.ets文件里。对应的主页Home组件,内容举例如下:


@Component
export default struct Home {build() {Column() {// 标题栏Text("首页").size({ width: '100%', height: 50 }).backgroundColor("#28bff1").fontColor("#ffffff").textAlign(TextAlign.Center).fontSize("18fp")// 内容项Text("首页").width('100%').height('100%').textAlign(TextAlign.Center).fontSize("25fp")}.size({ width: '100%', height: '100%' })}
}

3. 完整实现

import Home from "../pages/home/Home"
import ZhiHu from "../pages/zhihu/Zhihu"
import Mine from "../pages/mine/Mine"@Entry
@Component
struct Index {@State currentIndex: number = 0private controller: TabsController = new TabsController()// 只有被@Entry装饰的组件才可以调用页面的生命周期onPageShow() {console.info('Index onPageShow');}// 只有被@Entry装饰的组件才可以调用页面的生命周期onPageHide() {console.info('Index onPageHide');}// 只有被@Entry装饰的组件才可以调用页面的生命周期onBackPress() {console.info('Index onBackPress');}build() {Column() {Tabs({barPosition: BarPosition.End,controller: this.controller}) {TabContent() {Home()}.tabBar(this.TabBuilder('首页', 0, $r('app.media.icon_sort'), $r('app.media.icon_sort_default')))TabContent() {ZhiHu()}.tabBar(this.TabBuilder('日报', 1, $r('app.media.search_select'), $r('app.media.search_defaut')))TabContent() {Mine()}.tabBar(this.TabBuilder('我的', 2, $r('app.media.user_selected'), $r('app.media.user')))}.scrollable(false) // 禁止滑动切换}.width('100%').height('100%')}// 自定义导航页签的样式@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 ? '#28bff1' : '#8a8a8a')}.width('100%').height(50).justifyContent(FlexAlign.Center).onClick(() => {this.currentIndex = targetIndexthis.controller.changeIndex(this.currentIndex)})}
}

4. 总结

通过上述步骤,我们在HarmonyOS NEXT的应用中成功实现了一个简单的TabBar。这个TabBar包含了三个功能模块,并能够根据用户的操作进行动态更新。接下来,您可以在此基础上,进一步扩展更多功能,提升用户体验。希望这篇博文能够对您在HarmonyOS应用开发中有所帮助。

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢观影的朋友。

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

其他资源

HarmonyOS 鸿蒙应用开发( 五、快速实现ArkUI页面底部导航Tabs)_鸿蒙开发底部导航-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/445841.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建`mongodb`副本集-开启权限认证 mongo:7.0.5

搭建mongodb副本集-开启权限认证 mongo:7.0.5 1.5.1、创建文件 创建配置文件保存目录和数据保存目录 mkdir -p /data/mongodb/{/conf,/data,/logs}生成和设置权限 这个文件一定要在一个服务里面生成然后复制到其它服务器,所有服务器的这个key一定是相同的。 op…

Python数据分析-Scipy科学计算法

1.认识Scipy SciPy(发音为 "Sigh Pie")是一个开源的 Python 算法库和数学工具包。 通常与 NumPy、Matplotlib 和 pandas 等库一起使用,这些库共同构成了 Python 的科学计算基础。 2.使用Scipy基本函数 2.1 引用Scipy函数 impor…

HarmonyOS NEXT应用开发实战(二、封装比UniApp和小程序更简单好用的网络库)

网络访问接口,使用频次最高。之前习惯了uniapp下的网络接口风格,使用起来贼简单方便。转战到鸿蒙上后,原始网络接口写着真累啊!目标让鸿蒙上网络接口使用,简单程度比肩uniapp,比Axios更轻量级。源码量也不多…

antd table合并复杂单元格、分组合并行、分组合并列、动态渲染列、嵌套表头

项目里遇到个需求,涉及到比较复杂的单元格合并 、嵌套表头、分组合并行、合并列等,并且数据列还是动态的,效果图如下: 可以分组设置【显示列】例如:当前组为【合同约定】,显示列为【合同节点】和【节点金额…

文件完整性监控:如何提高企业的数据安全性

企业网络庞大而复杂,需要处理大量关键业务数据,这些敏感文件在企业网络中不断传输,并由多个用户和实体存储、共享和访问。FIM 工具或具有 FIM 功能的 SIEM 解决方案使企业能够跟踪未经授权的文件更改、对敏感信息的恶意访问、数据篡改尝试和内…

VSCode 使用 EmmyLua 对lua进行调试

时间:2024年10月 其他:win10,EmmyLua v0.8.20 参考:https://blog.csdn.net/ShenHaoDeHao/article/details/140268354 有几个概念搞清楚就好理解了。一般开发中,我们编写的lua文件由宿主程序的来解析、执行&#xff1…

[Linux#65][TCP] 详解 延迟应答 | 捎带应答 | 流量控制 | 拥塞控制

目录 一、延迟应答 二、捎带应答 三. 流量控制 总结 四. 拥塞控制 1. 拥塞控制 2. 慢启动机制: 3.思考 4.拥塞避免算法 5. 快速恢复算法 一、延迟应答 1. 立即应答问题 接收数据的主机若立刻返回ACK应答,可能返回的窗口较小。例如&#xff1…

RabbitMQ 入门(三)SpringAMQP

一、Spring AMQP 简介 SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。 SpringAmqp的官方地址:https://spring.io/projects/spring-amqp SpringAMQP提供了三个功能: - 自动…

【嵌入式软件-STM32】STM32简介

目录 一、STM32定义 二、STM32用途 三、STM32特点 四、STM32 四个系列 五、了解ARM 六、芯片解释 七、片上资源 八、命名规则 九、系统结构 内核 Flash DMA 外设种类和分布 十、引脚定义 类型 名称 引脚 十一、启动配置 十二、STM32最小系统电路 STM32及供电 供电引脚 滤波电容…

FFmpeg的简单使用【Windows】--- 视频倒叙播放

实现功能 点击【选择文件】按钮可以选择视频,当点击【开始处理】按钮之后,会先将视频上传到服务器,然后开始进行视频倒叙播放的处理,当视频处理完毕之后会将输出的文件路径返回,同时在页面中将处理好的视频展示出来。…

【特赞-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…

低代码开发技术:驱动MES系统创新与制造业数字化转型的融合之路

低代码开发与生产管理MES系统的融合,是当今制造业数字化转型的一个重要趋势。以下是对这一融合现象的详细分析: 一、低代码开发的概念与特点 低代码开发是一种通过图形化界面和预构建模块来简化应用程序开发过程的方法。它允许开发人员使用拖放组件和最…

【视觉分割新SOTA|论文解读2】一种最先进的图像分割模型——Segment Anything Model (SAM)模型架构!

【视觉分割新SOTA|论文解读2】一种最先进的图像分割模型——Segment Anything Model (SAM)模型架构! 【视觉分割新SOTA|论文解读2】一种最先进的图像分割模型——Segment Anything Model (SAM)模型架构! 文章目录 【视觉分割新SOTA|论文解读2】一种最先…

Matlab详细学习教程 MATLAB使用教程与知识点总结

Matlab语言教程 章节目录 一、Matlab简介与基础操作 二、变量与数据类型 三、矩阵与数组操作 四、基本数学运算与函数 五、图形绘制与数据可视化 六、控制流与逻辑运算 七、脚本与函数编写 八、数据导入与导出 九、Matlab应用实例分析 一、Matlab简介与基础操作 重点内容知识…

DM8数据库用户和表空间管理

1 说明 DM8用户管理和表空间管理常用的管理命令,包括创建、修改和查看信息操作等。 2 用户管理 2.1 创建用户 创建一个用户lu9up,密码为"admin2024.",未制定表空间,使用默认的表空间main。 SQL> create user lu…

八大排序--08快速排序

现有 arr {4,8,9,2,7}数组,请用快速排序的方式实现从小到大排序: 方法: 1.定义待排序数组中的第一个值为基准数; 2.定义j游标,从后向前移动找到第一个比基准数小的值停下; 3.定义i游标,从后向…

黑马程序员-redis项目实践笔记1

目录 一、 基于Session实现登录 发送验证码 验证用户输入验证码 校验登录状态 Redis代替Session登录 发送验证码修改 验证用户输入验证码 登录拦截器的优化 二、 商铺查询缓存 缓存更新策略 数据库和缓存不一致解决方案 缓存更新策略的最佳实践方案 实现商铺缓…

大数据毕业设计选题推荐-音乐数据分析系统-音乐推荐系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【C语言】使用结构体实现位段

文章目录 一、什么是位段二、位段的内存分配1.位段内存分配规则练习1练习2 三、位段的跨平台问题四、位段的应用五、位段使用的注意事项 一、什么是位段 在上一节中我们讲解了结构体,而位段的声明和结构是类似的,它们有两个不同之处,如下&…

Kubernetes(K8s)部署

主机名ip角色docker-harbor.revkarl.org172.25.254.250harbor仓库k8s-master172.25.254.100master,k8s集群控制节点k8s-node1172.25.254.10worker,k8s集群工作节点k8s-node2172.25.254.20worker,k8s集群工作节点 注意: 所有节点禁…