鸿蒙自定义Tab,可居左显示

最近写鸿蒙项目时,需要用到类似Android的TabLayout控件,鸿蒙官方也有提供类似实现的组件Tabs。但是官方Tabs组件,实在有点鸡肋,首先 TabContent和 TabBar是绑定在一起的放在Tabs里面的,如果UI是TabBar的背景是一个整体的,这时就受限了。另一个最令人吐槽的是,这个TabBar无法设置居左显示,它是默认居中的。
好吧,既然官方没有,就只能自己手动去实现了。
先看下效果:
在这里插入图片描述

一、首先,需要分析Tab组件点击滚动时的交互, 需要把目标Tab滚动到屏幕中间为止,那么就要计算 组件中线与屏幕中间的位置,从而得出需要滚动的距离,看下图会比较直观

在这里插入图片描述
那么就要首先要保存好每个Tab的坐标信息:

 @State tabDatas: Array<string> = []// tab : 保存好每个Tab的坐标信息.onAreaChange((old, newArea) => {this.tabAreas.set(index, newArea)})// scroll: 获取scroll组件的中线位置(屏幕的中线x坐标).onAreaChange((oldValue, newValue) => {this.scrollerMiddleX = (newValue.width as number) / 2})

然后拿中线x坐标减去屏幕的中线x坐标 得到的就是 Tab需要滚动中间距离:

 const selectedArea = this.tabAreas.get(index)const targetMiddleX = (selectedArea.width as number) / 2 + (selectedArea.globalPosition.x as number)const scrollOffsetX = targetMiddleX - this.scrollerMiddleX //滚动中间距离this.scroller.scrollTo({xOffset: this.scroller.currentOffset().xOffset + scrollOffsetX,//使用scrollTo,所以需要加上原有的偏移位置yOffset: 0,animation: { duration: 500 }})

至此,滚动功能就已经实现了。

二、然后就到Item组件的实现了,因为组件的样式是不确定的,需要交由外部去实现,这时就需要用到@BuilderParam了。
还有注意@BuilderParam如果需要按引用传递,需要把所有参数打包成一个对象,变量的改下才能传递触发事件

export class TabItemParam {item?: stringindex: number = 0selectIndex: number = 0
}@BuilderitemBuilder(item: TabItemParam ) {};@BuilderParam itemBuilderParam: (item: TabItemParam ) => void =this.itemBuilder;...ForEach(this.tabDatas, (item: string, index: number) => {Column() {this.itemBuilderParam({ item: item, index: index, selectIndex: this.selectedIndex })}...})
...

三、就是需要提供一个方法给外部去调用,触发滚动到指定的Tab。(不得不说,习惯了Android直接操作对象的方法的方式, 鸿蒙这种操作组件方法,实在有点绕。如果大家有其它更方便快捷的方式,可以评论分享下)

首先需要先定义一个Scroller,并且定义好一个给组件内部实现的方法A,一个给外部调用的方法B,并且 方法B内部是调用了方法A:

export class ZTabScroller {tabScroll?: (value: number) => void;scrollTo(index: number) {if (this.tabScroll) {this.tabScroll(index);}}
}

然后Tab在内部定义好scroller变量,并且在生命周期aboutToAppear()时定义好Scroller的方法A

  tabScroller?: TabScrolleraboutToAppear(): void {if (this.tabScroller) {this.tabScroller.tabScroll = (index: number) => {this.itemScrollCenter(index)  //触发滚动到指定Tab的方法}}}

这样外部就可以创建TabScroller对象,赋值给Tab组件,并且可调用scrollTo方法从而触发Tab内部的itemScrollCenter(index)方法了

四:外部使用

搭配上Swiper组件, 并关联上selectedIndex就可以达到效果啦。

  tabsData: Array<string> = []@State selectedIndex: number = 0@State pagerIndex: number = 1tabScroller = new TabScroller()aboutToAppear(): void {this.tabsData.push('tab1')this.tabsData.push('tab2')this.tabsData.push('tab3')}build() {Column(){TabComponent({tabDatas: this.tabsData,selectedIndex: this.pagerIndex,tabScroller: this.tabScroller,itemBuilderParam: this.tabItemBuilder,isFixedCenter:false,onPageSelectChange: (index) => {this.pagerIndex = index}})Swiper() {this.swiperItem(`0`,Color.Green)this.swiperItem(`1`,Color.Red)this.swiperItem(`2`,Color.Orange)}.index(this.pagerIndex).loop(false).indicator(false).onAnimationStart((index: number, targetIndex: number) => {this.tabScroller.scrollTo(targetIndex)}).padding({top:10}).height('100%').width('100%')}.padding({top:20}).height('100%').width('100%')}@BuilderswiperItem(text:string,color:ResourceColor){Text(text).width('100%').height('100%').backgroundColor(color).textAlign(TextAlign.Center).fontSize(30)}@BuildertabItemBuilder(item: TabItemData) {Column() {Text(item.title).height(25).fontSize(15).textAlign(TextAlign.Center).fontColor(item.index == item.selectIndex ? Color.Red : Color.Black).margin({ left: 15, right: 15 }).animatableFontSize(item.index == item.selectIndex ? 20 : 15).animation({ duration: 300, curve: Curve.Ease })if (item.index == item.selectIndex) {Blank().backgroundColor(Color.Blue).width(20).height(3).margin({ top: 5 }).borderRadius(2)}}};//加上一个字体的选中和放大的动画效果
@AnimatableExtend(Text)
function animatableFontSize(fontSize: Length) {.fontSize(fontSize)
}

至此,就完成整个效果了。

完整代码:
https://github.com/Zeng-Ke/Tabs_Harmony

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

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

相关文章

三十七、【人工智能】【机器学习】【监督学习】- AdaNet算法模型

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…

GPS叉车安全管理系统,远程监控管理车辆,保障叉车资产安全!

叉车的管理和监管一直是一个挑战&#xff0c;九盾叉车监管系统旨在实现对叉车资产的全面监管和管理&#xff0c;结合了GPS车辆定位技术&#xff0c;为您提供了实时、精确的叉车位置信息&#xff0c;从而帮助您更好地管理您的叉车资产。 一、IC卡指纹认证&#xff1a; 确保叉车…

工程数学线性代数(同济大学数学系)第六版(更新中)

第1章 行列式 2 全排列和对换 一、排列及其逆序数 全排列 1个逆序、逆序数 奇排列&#xff0c;偶排列 二、对换 对换&#xff1a;排列中任意两个元素对调 相邻对换&#xff1a;相邻两个元素对换 对换改变排列的奇偶性。 4 行列式的性质 5 行列式按行&#xff08;列&…

【网络】UDP和TCP之间的差别和回显服务器

文章目录 UDP 和 TCP 之间的差别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP API 的使用UDP APIDatagramSocket构造方法方法 DatagramPacket构造方法方法 回显服务器&#xff08;Echo Server&#xff09;1. 接收请求2. 根据请求计算响应3. 将…

极狐 GitLab 依赖扫描:助力开发者管理软件供应链

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

C#使用SharGL实现PUMA560机械臂

1、四轴机械臂 下载链接&#xff1a;https://download.csdn.net/download/panjinliang066333/89645225 关键代码 public void DrawRobot1(ref OpenGL gl,float[] angle,float[] yLength,bool isPuma560_Six){//坐标系说明&#xff1a;//①X轴正向&#xff1a;屏幕朝右//②Y轴…

Vue封装axios请求(超详细)

一、简介 Vue封装axios请求是指将axios库集成到Vue项目中,以便更方便地发送HTTP请求。首先,需要安装axios库,然后在Vue项目中创建一个名为request.js的文件,用于封装axios实例。在这个文件中,可以设置默认的配置,如基础URL、超时时间等。接下来,可以定义一些常用的请求方…

魔方远程时时获取短信内容APP 前端Vue 后端Ruoyi框架(含搭建教程)

前端Vue 后端Ruoyi框架 APP原生JAVA 全兼容至Android14(鸿蒙 澎湃等等) 前后端功能&#xff1a; ①后端可查看用户在线状态(归属地IP) ②发送短信(自定义输入收信号码以及短信内容&#xff0c;带发送记录) ③短信内容分类清晰(接收时间、上传时间等等) ④前后端分离以及A…

攸信动态丨CEIA电子智造论坛:聚焦高可靠性与智能制造,攸信技术受邀参展

第120届CEIA电子智造线下活动-导电高可靠性与智能制造&先进封装与系统集成创新发展论坛于8月8号&#xff0c;在厦门磐基希尔顿酒店召开&#xff0c;本次大会聚焦新型显示、EV汽车电子、智能家电等领域&#xff0c;受到了行业人士的重点关注&#xff0c;超300名行业同仁参会…

【网络】高并发场景处理:线程池和IO多路复用

文章目录 短时间内有大量的客户端的解决方案线程池IO 多路复用 短时间内有大量的客户端的解决方案 创建线程是比较经典的一种服务器开发模型&#xff0c;给每个客户端分配一个线程来提供服务 但一旦短时间内有大量的客户端&#xff0c;并且每个客户端请求都是很快的&#xff…

企业为什么需要安装加密软件

1. 数据保护 防止数据泄露&#xff1a;加密软件通过对敏感数据进行加密处理&#xff0c;确保即使数据在传输或存储过程中被截获&#xff0c;也无法被未授权人员读取或利用&#xff0c;从而有效防止数据泄露。 完整性保护&#xff1a;加密不仅保护数据的机密性&#xff0c;还通…

政务网站(.gov)专用SSL/HTTPS证书

政府网站在选择SSL证书时不仅需要遵循网络安全法规以及密评整改&#xff0c;更要提升公众信任度。国产服务商提供的专业版SSL证书&#xff0c;全方位符合政务部门对SSL证书的要求 1 算法要求 政务服务网站需要落实等保制度、密评制度&#xff0c;在密码应用上可选择国密算法S…

ubuntu-linux ifconfig只有回环IP问题解决

问题如下图所示&#xff1a; 解决方案&#xff1a; sudo dhclient

【Python学习-UI界面】PyQt5 小部件14-QDock 子窗口

可停靠窗口是一个子窗口&#xff0c;可以保持浮动状态或附加到主窗口的指定位置。 QMainWindow类的主窗口对象保留了一块区域供可停靠窗口使用。该区域位于中央窗口部件周围。 可停靠窗口可以在主窗口内移动&#xff0c;也可以被取消停靠并由用户移动到新的区域。 样式如下: …

关于鸣潮启动器450张图片杂谈—从代码分析为何使用帧动画

关于鸣潮启动器450张图片杂谈—从代码分析为何使用帧动画 前言 在鸣潮启动器的目录下 Wuthering Waves\kr_game_cache\animate_bg\99de27ae82e3c370286fba14c4fcb699打开该目录发现有450张图片&#xff0c;不难看出启动器的背景动画是由这450张图片不断切换实现的 qt框架 从…

2024千元以下蓝牙耳机有哪些推荐?四款年度性价比蓝牙耳机推荐

2024年&#xff0c;蓝牙耳机市场再次迎来了新的发展机遇与挑战&#xff0c;在众多的蓝牙耳机中&#xff0c;千元以下的产品因其较高的性价比而备受消费者青睐&#xff0c;那么面对琳琅满目的产品&#xff0c;2024千元以下蓝牙耳机有哪些推荐&#xff1f;接下来下面&#xff0c;…

【TM1638不能成功读回按键值】

8led8按键8数码管。主函数调用TM1638_ReadData2&#xff0c;打印了返回值&#xff0c;无论是否按键&#xff0c;都一直打印255&#xff0c;为什么全是1&#xff0c;看来读数据函数有问题啊。 u8 TM1638_ReadData2(void) {uint8_t i;uint8_t temp0x00;TM1638_DIOModeInput();/…

【机器学习西瓜书学习笔记——半监督学习】

机器学习西瓜书学习笔记【第十三章】 第十三章 半监督学习13.1 未标记样本13.2 生成式方法13.3 半监督 S V M SVM SVM基本思想优点和注意事项适用场景 13.4 图半监督标签传播算法多类标签传播算法Label PropagationLabel Spreading 13.5 基于分歧的方法数据视图协同训练 13.6 半…

CI/CD 自动化:最大限度地提高极狐GitLab 群组的“部署冻结”影响

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

基于LangChain手工测试用例转接口自动化测试生成工具!

接口自动化测试用例是一个老生常谈的问题&#xff0c;在未引入人工智能之前&#xff0c;也有非常多的生成方案&#xff0c;比如如下所示&#xff0c;通过har生成接口自动化测试用例&#xff1a; 但是以上的生成方式依然是有一些弊端&#xff0c;比如 har 本身虽然能表述一定的接…