最近有人问我,微信的最新版本的底部导航栏的动画的原理是什么。闲暇之余,我仔细瞅了瞅最新版本的微信,底部的动画非常可谓非常之有意思,这也是这篇文章的由来。
我想大家都安装有微信,大家可以自己看看自己手机上微信的底部导航栏的动画效果,然后再对比看看我实现的效果(如下图),几乎是一毛一样。
image
原理
首先,项目的架构是一个ViewPager加上底部导航栏,ViewPager的滑动可以产生一个滑动比例,底部导航栏根据这个比例值做相应的动画。那么,现在问题来了,底部导航栏如何实现。其实我们可以对底部导航栏的tab写一个自定义View,这个自定义View可以接收一个进度值(ViewPager产生的滑动比例值)来做一些动画。
实现
ViewPager的初始化代码我就不展示了,这个是基本功了,本文主要展示底部的Tab如何自定义View。
布局
这个自定义View的名字叫做TabView, 我选择让它继承自FrameLayout(继承其他的ViewGroup控件也可以的),并且加载一个如下的组合控件布局
// tab_layout.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent”
android:layout_height=“40dp”
android:gravity=“center_horizontal”
android:orientation=“vertical”>
<FrameLayout
android:layout_width=“wrap_content”
android:layout_height=“0dp”
android:layout_weight=“1”>
<ImageView
android:id=“@+id/tab_image”
android:layout_width=“wrap_content”
android:layout_height=“match_parent” />
<ImageView
android:id=“@+id/tab_image_top”
android:layout_width=“wrap_content”
android:layout_height=“match_parent” />
<TextView
android:id=“@+id/tab_title”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:textSize=“12sp” />
android:id=“@+id/tab_title"的TextView显示标题。android:id=”@+id/tab_image"的ImageView显示的是一个轮廓图片,也就是未选中时候的图片。android:id=“@+id/tab_image_top"的ImageView在android:id=”@+id/tab_image"的ImageView之上,显示的是选中时候的图片。轮廓图片和选中的图片,可以看下如下的图片例子
第一图片就是轮廓图片,第二个图片就是选中后的图片。为什么布局要这么设计呢?这当然是根据微信的动画而设计的布局(废话!),首先默认显示的是轮廓图片,当接收到一个进度值后,会让轮廓图片的轮廓变色,当进度值超过某个阈值的时候,让轮廓图片的透明度渐渐变为0(也就是完全透明,看不见),而让选中的图片的透明度渐渐变为255(也就是慢慢变清晰)。
TabView
既然知道了变色的原理,现在就来写TabView的代码吧。首先为TabView抽取自定义属性
// res/values/tabview_attrs.xml
<?xml version="1.0" encoding="utf-8"?>-
tabColor代表变色最终显示的颜色。
-
tabImage代表默认显示的轮廓图。
-
tabSelectedImage代表选中后的图。
-
tabTitle代表要显示的标题。
然后,在TabView中加载布局,并且获取自定义属性
public TabView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
// 加载布局
inflate(context, R.layout.tab_layout, this);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabView);
for (int i = 0; i < a.getIndexCount(); i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.TabView_tabColor:
// 获取标题和轮廓最终的着色
mTargetColor = a.getColor(attr, DEFAULT_TAB_TARGET_COLOR);
break;
case R.styleable.TabView_tabImage:
// 获取轮廓图
mNormalDrawable = a.getDrawable(attr);
break;
case R.styleable.TabView_tabSelectedImage:
// 获取选中图
mSelectedDrawable = a.getDrawable(attr);
break;
case R.styleable.TabView_tabTitle:
// 获取标题
mTitle = a.getString(attr);
break;
}
}
a.recycle();
}
当加载完布局后,需要为各个控件设置相应的属性
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// 1.设置标题,默认着色为黑色
mTitleView = findViewById(R.id.tab_title);
mTitleView.setTextColor(DEFAULT_TAB_COLOR);
mTitleView.setText(mTitle);
// 2.设置轮廓图片,不透明,默认着色为黑色
mNormalImageView = findViewById(R.id.tab_image);
mNormalDrawable.setTint(DEFAULT_TAB_COLOR);
mNormalDrawable.setAlpha(255);
mNormalImageView.setImageDrawable(mNormalDrawable);
// 3.设置选中图片,透明,默认着色为黑色
mSelectedImageView = findViewById(R.id.tab_selected_image);
mSelectedDrawable.setAlpha(0);
mSelectedImageView.setImageDrawable(mSelectedDrawable);
}
第二步中,为轮廓图调用了Drawable.setTint()方法为轮廓着色,默认着色为黑色。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
本文在开源项目GitHub中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
目前已经更新的部分资料,需要的自己取:
d)**
[外链图片转存中…(img-DMcwXwmi-1711377179528)]
最后
本文在开源项目GitHub中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
目前已经更新的部分资料,需要的自己取:
[外链图片转存中…(img-YCjss3qz-1711377179529)]
[外链图片转存中…(img-hMMoaJpw-1711377179529)]
[外链图片转存中…(img-NC0k3khA-1711377179529)]