当前位置: 首页 > news >正文

Android开发首页底部tab切换图标有动画效果

Android开发首页底部tab切换图标有动画效果

主页tab切换很正常,但往往加上写动画更好看

一、思路:

用属性动画,并且事先准备多张图片,用于切换后播放动画

二、效果图:

在这里插入图片描述单纯图看不出来,看下视频效果

Android开发教程实战案例源码分享-首页底部tab切换图标有动画效果

三、关键代码:
public class TabButtonGroup extends LinearLayout implements View.OnClickListener {private TabButton[] mTabButtons;private ViewPager mViewPager;private int mCurPosition;public TabButtonGroup(Context context) {this(context, null);}public TabButtonGroup(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public TabButtonGroup(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onFinishInflate() {super.onFinishInflate();int childCount = getChildCount();if (childCount > 0) {mTabButtons = new TabButton[childCount];for (int i = 0; i < childCount; i++) {View v = getChildAt(i);v.setTag(i);v.setOnClickListener(this);mTabButtons[i] = (TabButton) v;}}}public void setCurPosition(int position) {if (position == mCurPosition) {return;}if (mClickIntercepter != null && mClickIntercepter.needIntercept(position)) {return;}mTabButtons[mCurPosition].setChecked(false);mTabButtons[position].setChecked(true);mCurPosition = position;if (mViewPager != null) {mViewPager.setCurrentItem(position, false);}}@Overridepublic void onClick(View v) {Object tag = v.getTag();if (tag != null) {setCurPosition((int) tag);}}public void setViewPager(ViewPager viewPager) {mViewPager = viewPager;}public void cancelAnim() {if (mTabButtons != null) {for (TabButton tbn : mTabButtons) {if (tbn != null) {tbn.cancelAnim();}}}}public ClickIntercepter mClickIntercepter;public void setClickIntercepter(ClickIntercepter intercepter) {mClickIntercepter = intercepter;}public interface ClickIntercepter {boolean needIntercept(int position);}public void btnPerformClick(int position){if (mTabButtons != null&&mTabButtons[position]!=null) {mTabButtons[position].performClick();}}
}
public class TabButton extends LinearLayout {private Context mContext;private float mScale;private String mTip;private int mIconSize;private int mTextSize;private int mTextColorChecked;private int mTextColorUnChecked;private boolean mChecked;private ImageView mImg;private TextView mText;private Drawable[] mDrawables;private int mDrawaleArrayLength;private ValueAnimator mAnimator;private int mDrawableIndex;public TabButton(Context context) {this(context, null);}public TabButton(Context context, AttributeSet attrs) {this(context, attrs, 0);}public TabButton(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;mScale = context.getResources().getDisplayMetrics().density;TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TabButton);int iconArrayId = ta.getResourceId(R.styleable.TabButton_tbn_icon_array_id, 0);mTip = ta.getString(R.styleable.TabButton_tbn_tip);mIconSize = (int) ta.getDimension(R.styleable.TabButton_tbn_icon_size, 0);mTextSize = (int) ta.getDimension(R.styleable.TabButton_tbn_text_size, 0);mTextColorChecked = ta.getColor(R.styleable.TabButton_tbn_text_color_checked, 0);mTextColorUnChecked = ta.getColor(R.styleable.TabButton_tbn_text_color_unchecked, 0);mChecked = ta.getBoolean(R.styleable.TabButton_tbn_checked, false);ta.recycle();if (iconArrayId != 0) {TypedArray arr = getResources().obtainTypedArray(iconArrayId);int len = arr.length();int[] iconResArray = new int[len];for (int i = 0; i < len; i++) {iconResArray[i] = arr.getResourceId(i, 0);}arr.recycle();mDrawaleArrayLength = iconResArray.length;if (mDrawaleArrayLength > 0) {mDrawables = new Drawable[mDrawaleArrayLength];for (int i = 0; i < mDrawaleArrayLength; i++) {mDrawables[i] = ContextCompat.getDrawable(context, iconResArray[i]);}}}mAnimator = ValueAnimator.ofFloat(1, mDrawaleArrayLength - 1);mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float v = (float) animation.getAnimatedValue();int index = (int) v;if (mDrawableIndex != index) {mDrawableIndex = index;if (mImg != null) {mImg.setImageDrawable(mDrawables[index]);}}}});mAnimator.setDuration(500);mAnimator.setInterpolator(new LinearInterpolator());}@Overrideprotected void onFinishInflate() {super.onFinishInflate();setOrientation(VERTICAL);setGravity(Gravity.CENTER_HORIZONTAL);mImg = new ImageView(mContext);LayoutParams params1 = new LayoutParams(mIconSize, mIconSize);params1.setMargins(0, dp2px(4), 0, 0);mImg.setLayoutParams(params1);if (mDrawables != null && mDrawaleArrayLength > 0) {if (mChecked) {mImg.setImageDrawable(mDrawables[mDrawaleArrayLength - 1]);} else {mImg.setImageDrawable(mDrawables[0]);}}mText = new TextView(mContext);LayoutParams params2 = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);mText.setLayoutParams(params2);mText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);mText.setText(mTip);mText.setTextColor(mChecked ? mTextColorChecked : mTextColorUnChecked);addView(mImg);addView(mText);}public void setChecked(boolean checked) {mChecked = checked;if (mDrawables != null && mDrawaleArrayLength > 0) {if (mChecked) {if (mText != null) {mText.setTextColor(mTextColorChecked);}if (mAnimator != null) {mAnimator.start();}} else {if (mAnimator != null) {mAnimator.cancel();}if (mImg != null) {mImg.setImageDrawable(mDrawables[0]);}if (mText != null) {mText.setTextColor(mTextColorUnChecked);}}}}private int dp2px(int dpVal) {return (int) (mScale * dpVal + 0.5f);}public void cancelAnim() {if (mAnimator != null) {mAnimator.cancel();mAnimator.removeAllUpdateListeners();}}}
四、项目demo源码结构图:

在这里插入图片描述
有问题或者需要完整源码的私信我

相关文章:

Android开发首页底部tab切换图标有动画效果

Android开发首页底部tab切换图标有动画效果 主页tab切换很正常&#xff0c;但往往加上写动画更好看 一、思路&#xff1a; 用属性动画&#xff0c;并且事先准备多张图片&#xff0c;用于切换后播放动画 二、效果图&#xff1a; 单纯图看不出来&#xff0c;看下视频效果 An…...

Web前端高级工程师培训:异步处理专题

异步处理专题 课前准备 工具 编辑器 VSCode浏览器 Chorme 前置知识 ES6基础语法 课堂主题 同步及异步概念方块运动的实现promise的用法then的返还值Async 函数 和 await 课堂目标 理解并学会使用promise使用方式以及async 、await的使用 同步异步概念 js是单线程 单线程…...

ESP32-C3实现热点并在浏览器中输入域名访问网页

源代码 #include <WiFi.h> // 引入 WiFi 库&#xff0c;用于处理网络连接 #include <WebServer.h> // 引入 WebServer 库&#xff0c;用于创建 HTTP 服务器 #include <DNSServer.h> // 引入 DNSServer 库&#xff0c;用于处理 DNS 请…...

基于Python的自然语言处理系列(32):spaCy属性扩展

1. 介绍 在 spaCy 中,自定义扩展属性让我们能够为 Doc、Token 和 Span 对象添加元数据。通过这些扩展属性,开发者可以根据需要存储额外的上下文信息,或者动态计算属性值。 自定义属性通过点下划线(dot-underscore)属性访问,例如 token._.is_color。这种命名方式确保这些属…...

STM32 输入捕获模式详解:PWM 输入捕获与 PWI 模式(续篇)

在前两篇文章中&#xff0c;我们探讨了 STM32 输入捕获的基础和 PWI 模式的工作原理&#xff0c;特别是定时器的两个通道如何协同工作以捕获 PWM 信号。本文将进一步结合 STM32 标准库函数中的 TIM_PWMIConfig()&#xff0c;来讲解如何通过库函数配置定时器实现 PWI 模式。 我…...

【C++】set/map(重点解析)

目录 一、关联式容器和序列式容器 二、C中的键值对——pair 1.概念 2.定义 3.构造pair 三.set 1.construct构造 2.iterator迭代器 3.insert插入 4.erase删除 5.find查找 6.lower_bound和upper_bound 7.count 四.multiset 五.map 1.insert 2.operator[] 一、…...

【算法篇】动态规划类(1)(笔记)

目录 一、理论基础 1. 大纲 2. 动态规划的解题步骤 二、LeetCode 题目 1. 斐波那契数 2. 爬楼梯 3. 使用最小花费爬楼梯 4. 不同路径 5. 不同路径 II 6. 整数拆分 7. 不同的二叉搜索树 一、理论基础 1. 大纲 动态规划&#xff0c;英文&#xff1a;Dynamic Programm…...

mysql学习教程,从入门到精通,SQL 约束(Constraints)(41)

在数据库设计中&#xff0c;约束&#xff08;Constraints&#xff09;用于确保数据的准确性和完整性。它们通过限制可以插入到数据库表中的数据类型来防止无效数据。SQL 中有几种常见的约束类型&#xff0c;包括主键约束&#xff08;Primary Key&#xff09;、外键约束&#xf…...

使用CSS3与JavaScript实现炫酷的3D旋转魔方及九宫格交换动效

文章目录 前言一、项目需求背景二、CSS3 3D基础知识介绍2.1 什么是CSS3 3D&#xff1f;2.2 主要使用的CSS属性 三、使用HTML和CSS搭建魔方结构四、让魔方动起来&#xff1a;CSS3动画五、九宫格数字交换的JavaScript实现5.1 九宫格布局5.2 随机交换数字 六、随机交换与相邻格子的…...

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件

写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1&#xff1a;正文 一般的我们写springboot项目时配置文件是这个样子的&#xff1a; appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…...

GAN(Generative Adversarial Nets)

GAN(Generative Adversarial Nets) 引言 GAN由Ian J. Goodfellow等人提出&#xff0c;是Ian J. Goodfellow的代表作之一&#xff0c;他还出版了大家耳熟能详的花书&#xff08;Deep Learning深度学习&#xff09;&#xff0c;GAN主要的思想是同时训练两个模型&#xff0c;生成…...

linux下使用mpi求自然数和

搭建MPI并行计算环境&#xff0c;编写 MPI程序&#xff0c;求和 1 23....1 0000。 要求: 1.使用100个进程; 2.进程0计算1 2...100, 进程1计算101 102... 200, ..... 进程99计算9901 9902... 10000; 3.调用计时函数,分别输出每个进程的计算时间; 4.需使用MPI集群通信函数和同…...

WebGl学习使用attribute变量绘制一个水平移动的点

在WebGL编程中&#xff0c;attribute变量是一种特殊类型的变量&#xff0c;用于从客户端传递数据到顶点着色器。这些数据通常包括顶点的位置、颜色、纹理坐标等&#xff0c;它们是与每个顶点直接相关的信息。attribute变量在顶点着色器中声明&#xff0c;并且对于每个顶点来说都…...

机器学习四大框架详解及实战应用:PyTorch、TensorFlow、Keras、Scikit-learn

目录 框架概述PyTorch&#xff1a;灵活性与研究首选TensorFlow&#xff1a;谷歌加持的强大生态系统Keras&#xff1a;简洁明了的高层 APIScikit-learn&#xff1a;传统机器学习的必备工具实战案例 图像分类实战自然语言处理实战回归问题实战 各框架的对比总结选择合适的框架 1…...

linux源码安装slurm以及mung和openssl

一、源码安装munge 1、编译安装munge &#xff08;1&#xff09;下载munge地址&#xff1a;https://github.com/dun/munge/releases &#xff08;2&#xff09;解压编译安装&#xff1a; 1 2 3 4 5 6 7 8 创建/data目录 复制文件munge-0.5.15.tar.xz 到/data目录下 tar -Jx…...

分享蓝牙耳机A2DP音频卡顿原因及解决思路

背景 最近一直在更新博客&#xff0c;我觉得写博客有三个好处&#xff0c;一是很多东西时间久了就会忘&#xff0c;记下来方便自己以后回忆和总结&#xff0c;二是记下来可以加深自己对知识的理解&#xff0c;三是可以知识分享&#xff0c;方便他人。 言归正传&#xff0c;今天…...

Mac 下编译 libaom 源码教程

AV1 AV1是一种开放、免版税的视频编码格式&#xff0c;由开放媒体联盟&#xff08;AOMedia&#xff09;开发&#xff0c;旨在提供高压缩效率和优秀的视频质量。AV1支持多种分辨率&#xff0c;包括SD、HD、4K和8K&#xff0c;并适用于视频点播&#xff08;VOD&#xff09;、直播…...

【成品设计】基于Arduino平台的物联网智能灯

《基于Arduino平台的物联网智能灯》 整体功能&#xff1a; 这个任务中要求实现一个物联网智能灯。实际测试环境中要求设备能够自己创建一个热点&#xff0c;连接这个热点后能自动弹出控制界面&#xff08;强制门户&#xff09;。 功能点 基础功能 (60分) 要求作品至少有2个灯…...

安装和配置k8s可视化UI界面dashboard-1.20.6

安装和配置k8s可视化UI界面dashboard-1.20.6 1.环境规划2.初始化服务器1&#xff09;配置主机名2&#xff09;设置IP为静态IP3&#xff09;关闭selinux4&#xff09;配置主机hosts文件5&#xff09;配置服务器之间免密登录6&#xff09;关闭交换分区swap&#xff0c;提升性能7&…...

VLAN:虚拟局域网

VLAN:虚拟局域网 交换机和路由器协同工作后&#xff0c;将原先的一个广播域&#xff0c;逻辑上&#xff0c;切分为多个广播域。 第一步:创建VLAN [SW1]dispaly vlan 查询vlan VID&#xff08;VLAN ID&#xff09;:用来区分和标定不同的vlan 由12位二进制构成 范围: 0-4…...

从零到一:基于LLaMA-Factory与Ollama的本地大模型定制化实战

1. 为什么需要本地定制化大模型&#xff1f; 最近两年&#xff0c;大语言模型的发展速度简直让人瞠目结舌。从最初的GPT-3到现在的Llama 3&#xff0c;模型能力越来越强&#xff0c;但随之而来的问题是&#xff1a;这些通用大模型真的能满足我们每个人的特定需求吗&#xff1f;…...

如何用本地AI工具10倍提升视频字幕提取效率:video-subtitle-extractor完全指南

如何用本地AI工具10倍提升视频字幕提取效率&#xff1a;video-subtitle-extractor完全指南 【免费下载链接】video-subtitle-extractor 视频硬字幕提取&#xff0c;生成srt文件。无需申请第三方API&#xff0c;本地实现文本识别。基于深度学习的视频字幕提取框架&#xff0c;包…...

打破邮件营销壁垒:免费响应式HTML模板的实战指南

打破邮件营销壁垒&#xff1a;免费响应式HTML模板的实战指南 【免费下载链接】email-templates Free HTML email templates for Mailchimp and other emails services 项目地址: https://gitcode.com/gh_mirrors/ema/email-templates 一、邮件营销的隐形痛点与解决方案 …...

虚幻引擎+数字孪生:手把手搭建智慧校园三维可视化平台(附浙江工商大学实战案例)

虚幻引擎数字孪生&#xff1a;从零构建智慧校园三维可视化平台的完整指南 想象一下&#xff0c;清晨走进校园时&#xff0c;管理员已经在三维可视化平台上完成了安防巡查&#xff1b;教务主任通过热力图调整着今天的课程安排&#xff1b;后勤人员正根据实时数据优化能源分配——…...

3分钟解决NCM格式难题:ncmdumpGUI让你的音乐重获自由 [特殊字符]

3分钟解决NCM格式难题&#xff1a;ncmdumpGUI让你的音乐重获自由 &#x1f3b5; 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换&#xff0c;Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 还在为网易云音乐的NCM格式文件…...

Leather Dress Collection镜像免配置:预装SD1.5+12LoRA+app.py开箱即用

Leather Dress Collection镜像免配置&#xff1a;预装SD1.512LoRAapp.py开箱即用 想快速生成各种酷炫的皮革服装设计图&#xff0c;但被繁琐的模型下载、环境配置和参数调试劝退&#xff1f;今天介绍的Leather Dress Collection镜像&#xff0c;就是为你准备的“开箱即用”解决…...

【系统分析师_知识点整理】 8.项目管理

核心考向&#xff1a;进度管理&#xff08;计算 选择最高频&#xff09;&#xff1a;关键路径、ES/EF/LS/LF、总浮动时间、自由浮动时间、PDM 四种依赖、进度偏差分析&#xff1b;范围管理&#xff1a;WBS、范围确认、范围控制、范围边界定义&#xff1b;成本管理&#xff1a;…...

Reset Windows Update Tool:开源工具解决Windows更新问题的3个高效方案

Reset Windows Update Tool&#xff1a;开源工具解决Windows更新问题的3个高效方案 【免费下载链接】Reset-Windows-Update-Tool Troubleshooting Tool with Windows Updates (Developed in Dev-C). 项目地址: https://gitcode.com/gh_mirrors/re/Reset-Windows-Update-Tool …...

LabelImg图像标注工具:3分钟掌握高效目标检测数据标注技巧

LabelImg图像标注工具&#xff1a;3分钟掌握高效目标检测数据标注技巧 【免费下载链接】labelImg LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check ou…...

高效掌控暗影精灵设备:开源工具OmenSuperHub的四大突破

高效掌控暗影精灵设备&#xff1a;开源工具OmenSuperHub的四大突破 【免费下载链接】OmenSuperHub 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 告别原厂软件臃肿困扰&#xff0c;体验纯净硬件控制新方式 OmenSuperHub是一款专为惠普暗影精灵笔记本打造…...