ArkUI自定义TabBar组件
在ArkUI中的Tabs,通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。其中内容是图TabContent作为Tabs的自组件,通过给TabContent设置tabBar属性来自定义导航栏样式。现在我们就根据UI设计的效果图来实现下图效果:
根据上图分析可知,要实现以上效果需要下面这几步:
1、设置tabBar背景颜色,以及点击选中背景样式;
2、自定义导航栏指示器;
3、设置指示器跟随内容视图一起滑动切换效果。
设置tabBar背景颜色以及点击选中背景样式
1、首先我们需要使用@Builder修饰方法来表示这是一个自定义组件;
2、根据用户点击的tab索引和当前索引来设置背景图片和背景颜色,这里需要注意的是设置背景颜色的时候,注意左上角和右上角是有圆角的,需要根据索引判断是否展示圆角。
3、由于选中样式是带圆角的梯形,所以这里是用来3个不同的梯形切图。
@Builder
tabBuilder(title: string, targetIndex: number, selectImage: ResourceStr) {// 创建一个Column布局Column() {// 创建一个Text组件,显示标题Text(title)// 根据当前索引和目标索引判断字体颜色.fontColor(this.currentIndex === targetIndex ? $r("app.color.text_one") : $r("app.color.text_two"))// 设置字体大小为14.fontSize(14)// 根据当前索引和目标索引判断字体粗细.fontWeight(this.currentIndex === targetIndex ? 600 : 400)}// 设置Column的宽度为100%.width('100%')// 设置Column的高度为100%.height("100%")// 设置Column的子组件垂直居中对齐.justifyContent(FlexAlign.Center)// 根据当前索引和目标索引判断是否设置背景图片.backgroundImage(this.currentIndex == targetIndex ? selectImage : null)// 设置Column的背景颜色.backgroundColor($r("app.color.bg_data_color"))// 根据目标索引判断是否需要设置顶部左右圆角.borderRadius({ topLeft: targetIndex == 0 ? 8 : 0, topRight: targetIndex == 2 ? 8 : 0 })// 设置背景图片填充方式为填充整个容器.backgroundImageSize(ImageSize.FILL)
}
自定义导航栏指示器
由于指示器需要跟随内容视图一起滑动切换,所以指示器不能在单个tabBuilder中设置。
1、使用Column组件定义底部指示器,设置一个宽度为文字宽度,高度为3的蓝色指示器;
2、这里的指示器宽度可以动态设置成文字的宽度,也可以直接设置成文字某个固定宽度;
3、指示器距离左边的距离需要动态设置,配上动画,可以实现指示器跟随手指滑动。
Stack() {Tabs({ barPosition: BarPosition.Start }) {TabContent() {this.tripPage()}.tabBar(this.tabBuilder("房源", 0, $r("app.media.trip_data_start_bg"))).align(Alignment.TopStart).margin({ top: 54 })............}.backgroundColor($r("app.color.white")).borderRadius(8).barHeight(44).width("93.6%").height(380).onChange((index) => {this.currentIndex = index})//自定义指示器,设置一个宽度为文字宽度,高度为3的蓝色指示器Column().width(this.indicatorWidth).height(3).backgroundColor($r("app.color.main_color")).margin({ left: this.indicatorLeftMargin, top: 42 }).borderRadius(1)
}
添加指示器动画
要实现指示器跟随手指滑动,切换不同的tab,需要为指示器添加动画,监听Tabs动画开始和动画结束,以及手势监听。
/*** 启动动画至指定位置** @param duration 动画时长* @param leftMargin 动画结束后的左边距* @param width 动画结束后的宽度*/private startAnimateTo(duration: number, leftMargin: number, width: number) {// 设置动画开始标志为truethis.isStartAnimateTo = trueanimateTo({// 动画时长duration: duration, // 动画时长// 动画曲线curve: Curve.Linear, // 动画曲线// 播放次数iterations: 1, // 播放次数// 动画模式playMode: PlayMode.Normal, // 动画模式// 动画结束时的回调函数onFinish: () => {// 将动画开始标志设置为falsethis.isStartAnimateTo = false// 输出动画结束信息console.info('play end')}}, () => {// 设置指示器的左边距this.indicatorLeftMargin = leftMargin// 设置指示器的宽度this.indicatorWidth = width})}
1、动画开始的监听
Tab切换动画开始时,动画返回的目标索引设置为当前索引,调用startAnimateTo方法,给指示器设置动画,动态设置指示器的左边距。
Tabs({ barPosition: BarPosition.Start }) {}.onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {// 切换动画开始时触发该回调。指示器跟着页面一起滑动。this.currentIndex = targetIndexthis.startAnimateTo(this.animationDuration, this.textInfos[targetIndex][0], this.textInfos[targetIndex][1])})
2、动画结束的监听
tab切换动画结束时,回触发onAnimationEnd监听。
Tabs({ barPosition: BarPosition.Start }) {}.onAnimationEnd((index: number, event: TabsAnimationEvent) => {// 切换动画结束时触发该回调。指示器动画停止。let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event)this.startAnimateTo(0, currentIndicatorInfo.left, currentIndicatorInfo.width)})
3、手势滑动监听
在页面跟手滑动过程中,逐帧触发该回调。
Tabs({ barPosition: BarPosition.Start }) {}
.onGestureSwipe((index: number, event: TabsAnimationEvent) => {// 在页面跟手滑动过程中,逐帧触发该回调。let currentIndicatorInfo = this.getCurrentIndicatorInfo(index, event)//设置当前索引this.currentIndex = currentIndicatorInfo.index//设置指示器距离左边间距this.indicatorLeftMargin = currentIndicatorInfo.left//指示器宽度设置this.indicatorWidth = currentIndicatorInfo.width})
封装获取指示器信息方法,返回指示器的索引,左边距和指示器宽度,在手势滑动监听中调用该方法,可以动态获取指示器的左边距,配合动画,可以实现指示器跟随手势滑动。从而实现UI设计效果。
/*** 获取当前指示器信息** @param index 当前索引* @param event Tabs动画事件* @returns 包含指示器索引、左边距和宽度的对象*/private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record<string, number> {// 当前Tab的索引let nextIndex = index// 如果当前索引大于0且滑动偏移量大于0,表示向左滑动,将nextIndex减1if (index > 0 && event.currentOffset > 0) {nextIndex--}// 如果当前索引小于3且滑动偏移量小于0,表示向右滑动,将nextIndex加1else if (index < 3 && event.currentOffset < 0) {nextIndex++}// 获取当前索引对应的Tab信息let indexInfo = this.textInfos[index]// 获取nextIndex对应的Tab信息let nextIndexInfo = this.textInfos[nextIndex]// 计算滑动比例let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth)// 如果滑动比例大于0.5,则将currentIndex设为nextIndex,表示切换到下一页的tabBar// 页面滑动超过一半,tabBar切换到下一页。let currentIndex = swipeRatio > 0.5 ? nextIndex : index// 根据滑动比例计算当前Tab的左边距let currentLeft = indexInfo[0] + (nextIndexInfo[0] - indexInfo[0]) * swipeRatio// 根据滑动比例计算当前Tab的宽度let currentWidth = indexInfo[1] + (nextIndexInfo[1] - indexInfo[1]) * swipeRatio// 返回包含当前Tab索引、左边距和宽度的对象return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth }}
相关文章:
ArkUI自定义TabBar组件
在ArkUI中的Tabs,通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。其中内容是图TabContent作为Tabs的自组件,通过给TabContent设置tabBar属性来自定义导航栏样式。现在我们就根据UI设计的效果图来实现下图效果: 根…...
pair类型应用举例
在main.cpp里输入程序如下: #include <iostream> //使能cin(),cout(); #include <utility> //使能pair数据类型; #include <string> //使能string字符串; #include <stdlib.h> //使能exit(); //pair类型可以将两个相同的或不同类…...
数字 图像处理算法的形式
一 基本功能形式 按图像处理的输出形式,图像处理的基本功能可分为三种形式。 1)单幅图像 单幅图像 2)多幅图像 单幅图像 3)单(或多)幅图像 数字或符号等 二 几种具体算法形式 1.局部处理邻域对于任一…...
安徽对口高考Python试题选:输入一个正整数,然后输出该整数的3的幂数相加形式。
第一步:求出3的最高次幂是多少 guoint(input("请输入一个正整数:")) iguo a0 while i>0: if 3**i<guo: ai break ii-1print(a)#此语句为了看懂题目,题目中不需要打印出最高幂数 第二步…...
Node.js是什么? 能做什么?
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它使用事件驱动、非阻塞式I/O模型,使得JavaScript能够在服务器端运行。Node.js允许JavaScript脱离浏览器,直接在服务器和计算机上使用,极大地扩展了JavaScript的应用范围。…...
JVM快速入门
1、 JVM探究 面试问题 :谈谈对JVM的理解? java8虚拟机和之前的变化更新?什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?JVM的常用调优参数有哪些?内存快照如何抓取,怎么分析Dump文件?知道吗?谈谈JVM中,类加载器你的认识?2、JVM的位置 3、JVM的体系结构 3.1…...
理解深度学习模型——高级音频特征表示的分层理解
理解深度学习模型可以是一个复杂的过程,因为这些模型通常包含大量的参数和层次。 (1)复杂性来源: 深度学习模型的复杂性来源于多个方面,包括模型的规模、层次结构、参数数量以及训练数据的复杂性。以下是一些关键点&a…...
【HarmonyOS Next】原生沉浸式界面
背景 在实际项目中,为了软件使用整体色调看起来统一,一般顶部和底部的颜色需要铺满整个手机屏幕。因此,这篇帖子是介绍设置的方法,也是应用沉浸式效果。如下图:底部的绿色延伸到上面的状态栏和下面的导航栏 UI 在鸿蒙…...
数据结构 ——— 树的概念及结构
目录 树的结构以及示意图 树的概念编辑 树的结构与递归的关系编辑 树的结构以及示意图 树是一种非线性的数据结构,它是由 n(n>0) 个有限节点组成一个具有层次关系的集合 把这种结构叫做树是因为它看起来像一棵倒挂的树 特点: 有一个特殊的…...
初探Vue前端框架
文章目录 简介什么是Vue概述优势MVVM框架 Vue的特性数据驱动视图双向数据绑定指令插件 Vue的版本版本概述新版本Vue 3Vue 3新特性UI组件库UI组件库概述常用UI组件库 安装Vue安装Vue查看Vue版本 实例利用Vue命令创建Vue项目切换工作目录安装vue-cli脚手架创建Vue项目启动Vue项目…...
Lucas带你手撕机器学习——岭回归
岭回归(Ridge Regression) 一、背景与引入 在进行线性回归分析时,我们常常面临多重共线性的问题。多重共线性指的是自变量之间高度相关,这会导致回归系数的不稳定性,使得模型的预测能力降低。传统的线性回归通过最小…...
C2W4.LAB.Word_Embedding.Part1
理论课:C2W4.Word Embeddings with Neural Networks 文章目录 Word Embeddings First Steps: Data PreparationCleaning and tokenizationSliding window of wordsTransforming words into vectors for the training setMapping words to indices and indices to w…...
hive初体验
1.首先,确保启动了Metastore服务。 runjar就是metastore进程 2.进入hive客户端: 命令:hive 3.操作:没有指定数据库时默认在default 一:创建表:CREATE TABLE test(id INT, name STRING, gender STRING); 完成,show tables看一下 也可以通过hdfs文件系统查看,默认路径…...
云渲染主要是分布式(分机)渲染,如何使用blender云渲染呢?
云渲染主要是分布式(分机)渲染,比如一个镜头同时开20-100张3090显卡的机器渲染,就能同时渲染20-100帧,渲染不仅不占用自己电脑,效率也将增加几十上百倍! blender使用教程如下: 第一…...
WordPress与WP Engine:关键事件时间线
WordPress与WP Engine:关键事件时间线 以下时间线突出了9月和10月之间这场不断升级的WordPress与WP Engine冲突中的关键事件: 9月21日:Matt Mullenweg发布了一篇名为“WP Engine不是WordPress”的博客。 9月22日:Mullenweg批评…...
大数据治理平台建设规划方案(71页WORD)
随着信息化时代的到来,大数据已成为企业管理和决策的重要基础。然而,大数据的快速增长和复杂性给数据的管理和治理带来了巨大挑战。为了有效应对这些挑战,构建一个高效、稳定的大数据治理平台显得尤为重要。 文档介绍: 该平台旨在…...
Maven 项目管理工具
目录 Maven简介 Maven快速上手 Maven详细介绍 Maven工作机制 Maven安装及配置 使用IDEA创建Maven Web工程 Maven简介 Maven是 Apache 开源组织奉献的一个开源项目,可以翻译为“专家”或“内行”。 Maven 的本质是一个项目管理工具,将项目开发和管…...
ubuntu开机启动jar
要在Ubuntu系统上开机启动一个jar文件,你可以创建一个systemd服务单元。以下是创建服务并设置开机启动的步骤: 创建一个新的systemd服务文件。 打开一个新的服务文件,例如/etc/systemd/system/your-service.service,使用你喜欢的…...
【目标检测02】非极大值抑制 NMS
文章目录 1. 前言2. 原理3. 代码实现 1. 前言 在检测图像中的目标时,一个目标可能会被预测出多个矩形框,而实际上我们只需要一个,如何消除冗余的边界框呢?一种方简单的方案是提升置信度的阈值,过滤掉低置信度的边界框…...
104协议调试工具
在学习104协议过程中,通过直接阅读协议的学习方式会略有枯燥,这里把常用的104调试、测试工具介绍给大家,以便快速的进行模拟通信来更好的了解、学习104协议。 通信协议分析及仿真软件是非常重要的测试工具,该软件支持 101,104,mo…...
日常记录:es TransportClient添加证书处理
背景 最近在搞es登录,不知道是不是低版本问题(6.8.12),开启登录之后springboot连接es,es一直报Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 45530000002c000000000000009108004d3…...
apply call bind 简介
Function.prototype.call(thisArg [, arg1, arg2, …]) call() 简述 call() 方法 调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。当第一个参数为 null、undefined 的时候, 默认 this 上下文指向window。 call() 简单实例 const name …...
数据结构 单调栈
应用情景 求当前元素 前面/后面,第一个比它 小/大 的元素的 值/下标/下标距离 优点 剔除重复寻路操作,将暴力 O(n^2) 优化到 O(n) 性质 从栈底开始,元素 单调递增/单调递减 单调性视具体情景而定 (找较大值还是较小值、找的方向) 思路…...
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置
本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师) 由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序࿰…...
基于flask和neo4j的医疗知识图谱展示问答系统
如果你仍在为毕业设计的选题发愁,或者想通过技术项目提升专业实力,这个基于Flask和Neo4j的医疗知识图谱展示与问答系统,绝对是个不错的选择! 项目亮点大揭秘: 知识图谱与问答结合:我们采用了医疗场景下的知…...
Python——脚本实现datax全量同步mysql到hive
文章目录 前言一、展示脚本二、使用准备1、安装python环境2、安装EPEL3、安装脚本执行需要的第三方模块 三、脚本使用方法1、配置脚本2、创建.py文件3、执行脚本4、测试生成json文件是否可用 前言 在我们构建离线数仓时或者迁移数据时,通常选用sqoop和datax等工具进…...
Python爬虫教程:从入门到精通
Python爬虫教程:从入门到精通 前言 在信息爆炸的时代,数据是最宝贵的资源之一。Python作为一种简洁而强大的编程语言,因其丰富的库和框架,成为了数据爬取的首选工具。本文将带您深入了解Python爬虫的基本概念、实用技巧以及应用…...
pytorh学习笔记——cifar10(四)用VGG训练
1、新建train.py,执行脚本训练模型: import os import timeimport torch import torch.nn as nn import torchvisionfrom vggNet import VGGbase, VGGNet from load_cifar import train_loader, test_loader import warnings import tensorboardX# 忽略…...
CRLF、UTF-8这些编辑器右下角的选项的意思
经常使用编辑器的小伙伴应该经常能看到右下角会有这么两个选项,下图是VScode中的示例,那么这两个到底是啥作用呢? 目录 字符编码ASCII 字符集GBK 字符集Unicode 字符集UTF-8 编码 换行 字符编码 此部分参考博文 在计算机中,所有…...
【C++干货篇】——类和对象的魅力(四)
【C干货篇】——类和对象的魅力(四) 1.取地址运算符的重载 1.1const 成员函数 将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面。const实际修饰该成员函数隐含的this指针(this指向的对…...
周到的宁波网站建设/怎么制作网页教程
调用实例: 该方法将本地的E盘文件test.doc上传到接口服务器上的 uploadFile方法中,uploadFile会对上传的文件做进一步处理。 若你想自己对上传的文件做操作,将接口uploadFile改为自己写好的方法就行了。 CURL方法如下: public fun…...
息烽做网站公司有哪些/网站seo关键词优化技巧
Deadline: 2018-12-24 10:00PM,以提交至班级博客时间为准。 如果你觉得你的总评成绩不理想或者希望再提高,请根据博客要求,写一篇个人随笔 参考来自:http://www.cnblogs.com/xinz/archive/2012/03/26/2417699.html&…...
横峰县建设局网站/crm系统
0.巨大的地址空间这个已经不用再说了。除了空间巨大,固定长度的前缀分配也使得地址分配更加均衡。1.ICMPv6真正的有了用武之地:地址/路由配置的自动化IPv6使得联网设备真的成了即插即用,一切都是通过自动生成的链路本地地址开始的,…...
石狮网站建设报价/石嘴山网站seo
1.查出占用端口的进程: 比如我要查找的8080,1099端口: netstat -ano|findstr 8080 netstat -ano|findstr 1099 12424就是我们所查进程的id,然后干掉它 taskkill -f -pid 12424...
扬中市做网站/免费推广产品的网站
忽然之间,美国食品药物管理局(以下简称FDA)成了AI医疗亲密无间的好朋友和坚定的支持者。 2018年上半年,FDA相继批准癫痫监测与警报AI手表Embrace、AI临床监测平台Wave、脑卒中护理软件Viz.ai、自闭症筛查AI软件Cognoa以及血糖预测…...
桓台新城建设有限公司网站/郑州企业网站优化排名
用hbase做数据库,但由于hbase没有类sql查询方式,所以操作和计算数据非常不方便,于是整合hive,让hive支撑在hbase数据库层面 的 hql查询.hive也即 做数据仓库 1. 基于HadoopHive架构对海量数据进行查询:http://blog.csdn.net/kunshan_shenbin/article/details/710531…...