前言
在 打造自己的 PagerTab 之一 (给 Tab 添加红点) 中,我们实现了给 PagerSlidingTabStrip 暴漏一个接口,使它可以通过 android-viewbadger 很方便的给指定 Tab 添加红点显示。那么这次我们要实现让选中的 Tab 变换颜色。
效果图
我们实现的效果:
分析
在上一章中我们实现了给 Tab 添加红点,这里简单回顾下,给 Tab 添加红点,实际上是把当前的 Tab 从原来的父视图中移除,然后放到一个包含 TextView 的 FrameLayout 中。那么我们要切换 Tab 的颜色,首先要获取到 Tab 中的文字(TextView)或者图片(ImageView),通过给相应的视图设置不同的透明度来实现文本或者图片颜色的变化。
代码及解析
我们定义了一个默认未选中状态的透明度,根据这个透明度,只要通过 setTextColor() 方法设置了文本颜色,都会自动生成对应的未选中颜色,代码如下:
//默认透明度
private int defaultAlpha = 0xA0000000;
private int tabTextColorNormal= (tabTextColor & 0x00FFFFFF) | defaultAlpha;
//设置文字颜色后,自定生成对应的未选中颜色,并且在 updateTabStyles() 中,把所有 TextView 的文字颜色都设置成未选中的颜色。
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
//http://stackoverflow.com/questions/28483497/change-int-color-opacity-in-java-android
this.tabTextColorNormal = (textColor & 0x00FFFFFF) | defaultAlpha;
updateTabStyles();
}
根据上一章我们知道 Tab 的类型为两种,分别为 TextView 和 ImageButton,而且如果使用 android-viewbadger 项目后,TextView 或者 ImageButton 会嵌套在 FrameLayout 中,所以我们首先来获取到对应的 TextView 或者 ImageButton。
由于 ImageButton 不存在设置颜色的问题,所以在初始化 ImageButton 时,设置对应的透明度。
在 onDraw() 方法中,把默认位置(也就是 position 为 0)的 Tab 颜色设置为选中时的颜色,用于 Tab 有两种类型,所以这里需要做一下判断处理,代码如下:
//在 onDraw 中调用更新 Tab 颜色的方法更新默认选中 Tab 的颜色
updateTabColor(tabsContainer.getChildAt(currentPosition), tabTextColor);
//首先判断 Tab 的类型,再根据类型做不同的处理
private void updateTabColor(View tabView, int value) {
if (tabType == TAB_TYPE_TEXT) {
updateTextViewColor(tabView, value);
} else {
updateImageButtonAlpha(tabView, value);
}
}
//更新 Tab 透明度(根据获取 Tab 对应类型的对象,设置透明度)
private void updateTextViewColor(View tabView, int color) {
if (tabView instanceof TextView) {
((TextView) tabView).setTextColor(color);
} else if (tabView instanceof FrameLayout
&& ((FrameLayout) tabView).getChildAt(0) instanceof TextView) {
((TextView) ((FrameLayout) tabView).getChildAt(0)).setTextColor(color);
}
}
通过上面的步骤,Tab 初始化的样式就已经完成了,接下里只需要在滑动时给对应的 Tab 改变颜色就可以了。
在滑动 ViewPager 时,可以获取到 ViewPager 的偏移量,根据偏移量来更新 Tab 的颜色,就可以达到我们想要的效果了:
if(currentPositionOffset > 0.5) {
updateTabColor(currentTab, tabTextColorNormal);
updateTabColor(nextTab, tabTextColor);
} else {
updateTabColor(currentTab, tabTextColor);
updateTabColor(nextTab, tabTextColorNormal);
}