微信6.0的时候就出现有了底部Tab切换透明度变化的效果,趁着周末也抽空来实现一下,其实十分简单,我们先来看一下效果:
嗯,没错,又是偷的图
原图来自:http://upload-images.jianshu.io/upload_images/2552605-8cf01f84f3a344d3?imageMogr2/auto-orient/strip
效果大概就跟上图一模一样吧。,所以我就懒得自己录制了。
首先我们拿到这一个需求,操起我们的笔和纸,将你知道的一些用于实现的思路写下来,要养成一个良好的习惯哦。
解剖后大概能知道:1,ViewPager和Fragment结合使用(此处用FragmentPagerAdapter)
2,可能需要两套图,选中状态套餐A(就是那个绿帽子颜色的),未选中时的套餐B(被绿后世界都变成灰色了)
3,需要动态的获取position以及positionOffset,然后拿到左右两个View,设置positionOffset (这个值时关键!!!);
4,处理点击时图片文字切换
哇靠,原来就这么简单。
那么这里最骚的操作在哪里呢,就是重中之重的第三步操作了!!
有些同学可能会疑问positionOffset是什么,怎么用?
这里给大家简单通过一道数学题目来解释一下,我们大家都解过方程式吧,such as:y=1-x;我们画个图,大概长这样:
y随着x的递增而减小。
其实我们的滑动处理和这个函数的一模一样的,我们当前选中项的绿色透明度为1,下一个Tab的值为0(Y),positionOffset的值即为X。
好的,本文分析到此结束!
同学可以下课自己实现了
我也偷偷打开我的Android studio实现了一波:
首先我们看xml代码,我们需要在xml中通过相对布局或者FramLayout来将绿色图套在灰色图之上!!!(因为无论透明度如何发现改变,只是针对绿色图片,我!们!底!部!的!灰!色!图!片!一!直!都!在!)。
我们每个tab都应该时这样处理的,这里给出一个,另外三个是一样的。文末给出完整代码
<RelativeLayout android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:id="@+id/rl_mine"
android:layout_width="0dp">
<!--正常显示时的图片-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/mine_normal" />
<!--选中时的图片-->
<ImageView
android:id="@+id/mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/mine_selected" />
<!--正常显示的文字颜色-->
<TextView
android:layout_centerHorizontal="true"
android:layout_below="@+id/mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="我"
/>
<!--选中时显示的文字颜色-->
<TextView
android:textColor="#46c01b"
android:id="@+id/mine_tv"
android:layout_centerHorizontal="true"
android:layout_below="@+id/mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="我"
/>
</RelativeLayout>
接下来好戏登场了,我们开始编写Java代码啦。
首先创建一个TabFragment,大致如下:
public class TabFragment extends Fragment{
//默认显示文字
private String content ="default";
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
/**
* 通过Arguments获取传来的参数,与getActivity.getIntent.getXXX("xxx")相比,此方式实现了与Activity的解耦
* 使得我们的TabFragment可以复用。
*/
if (getArguments()!=null){
content = getArguments().getString("content");
}
TextView textView = new TextView(getContext());
textView.setGravity(Gravity.CENTER);
textView.setText(content);
textView.setTextSize(26);
textView.setBackgroundColor(Color.parseColor("#ffffffff"));
return textView;
}}
Fragment创建好了,还是非常简单的,无非就是一个TextView,这里为了方便复用Fragment,不通过编写多套布局的方式一个一个Inflate。
Activity:
第一步,findById,这里我是用ButterKnife插件,就不一一find了。
@BindView(R.id.viewPager)
ViewPager viewPager;//ViewPager
@BindView(R.id.home)
ImageView home;//绿色的微信图片
@BindView(R.id.home_tv)
TextView homeTv;//绿色的微信文字
@BindView(R.id.rl_home)
RelativeLayout rlHome;
@BindView(R.id.category)
ImageView category;//绿色的通讯录图片
@BindView(R.id.category_tv)
TextView categoryTv;//绿色的通讯录文字
@BindView(R.id.rl_category)
RelativeLayout rlCategory;
@BindView(R.id.service)
ImageView service;//绿色的发现图片
@BindView(R.id.service_tv)
TextView serviceTv;//绿色的发现文字
@BindView(R.id.rl_service)
RelativeLayout rlService;
@BindView(R.id.mine)
ImageView mine;//绿色的我图片
@BindView(R.id.mine_tv)
TextView mineTv;//绿色的我文字
@BindView(R.id.rl_mine)
RelativeLayout rlMine;
private MyPagerAdapter adapter;//适配器
private List<Fragment> mTabs = new ArrayList<>();//Fragment集合
private List<ImageView> images = new ArrayList<>();//绿色图片集合
private List<TextView> texts = new ArrayList<>();//绿色文字集合
private String[] mContents = new String[]{"微信", "通讯录", "发现", "我"};//Fragment中TextView显示内容
第二步:初始化数据:
private void initData() {
//创建TabFragment
for (int i = 0; i < mContents.length; i++) {
TabFragment tabFragment = new TabFragment();
Bundle bundle = new Bundle();
bundle.putString("content", mContents[i]);
tabFragment.setArguments(bundle);
mTabs.add(tabFragment);
}
images.add(home);
images.add(category);
images.add(service);
images.add(mine);
texts.add(homeTv);
texts.add(categoryTv);
texts.add(serviceTv);
texts.add(mineTv);
setselectedTabColor(0);
}
上面创建了四个TabFragment,并且将我们的绿色图片和绿色文字分别添加到集合中,方便后期做切换处理。
第三步:编写FragmentPagerAdapter并绑定。
private class MyPagerAdapter extends FragmentPagerAdapter {
//构造方法
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
//返回当前Fragment
@Override
public Fragment getItem(int position) {
return mTabs.get(position);
}
//返回Fragment个数
@Override
public int getCount() {
return mTabs.size();
}
}
记得在Activity中的onCreate方法中绑定适配器:
viewPager.setAdapter(adapter = new MyPagerAdapter(getSupportFragmentManager()));
viewPager.setOnPageChangeListener(this);
第四步:实现ViewPager的onPagerChangeListener方法
implements ViewPager.OnPageChangeListener
第五步:实现底部Tab选中时图片和文字的切换:
private void setselectedTabColor(int pos) {
images.get(0).setAlpha(0f);
images.get(1).setAlpha(0f);
images.get(2).setAlpha(0f);
images.get(3).setAlpha(0f);
texts.get(0).setAlpha(0f);
texts.get(1).setAlpha(0f);
texts.get(2).setAlpha(0f);
texts.get(3).setAlpha(0f);
images.get(pos).setAlpha(1f);
texts.get(pos).setAlpha(1f);
}
第六步:实现透明度变化方法:
private void changeAlpha(int pos, float posOffset) {
int nextIndex = pos + 1;
if (posOffset > 0) {
//设置tab的颜色渐变效果
images.get(pos).setAlpha(1f - posOffset);
images.get(nextIndex).setAlpha(posOffset);
texts.get(pos).setAlpha(1f-posOffset);
texts.get(nextIndex).setAlpha(posOffset);
}
}
第七步:重写OnPageChangeListener的onPageScrolled,onPageSelected的方法:
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
changeAlpha(position, positionOffset);
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 0:
setselectedTabColor(0);
break;
case 1:
setselectedTabColor(1);
break;
case 2:
setselectedTabColor(2);
break;
case 3:
setselectedTabColor(3);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
最后一步:处理点击事件中Fragment切换和底部Tab切换:
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.rl_home:
viewPager.setCurrentItem(0, false);
setselectedTabColor(0);
break;
case R.id.rl_category:
viewPager.setCurrentItem(1, false);
setselectedTabColor(1);
break;
case R.id.rl_service:
viewPager.setCurrentItem(2, false);
setselectedTabColor(2);
break;
case R.id.rl_mine:
viewPager.setCurrentItem(3, false);
setselectedTabColor(3);
break;
}
}
这里需要注意的时viewPager.setCurrentItem方法,第二个参数为是否启用ViewPager滑动时的动画效果,我们这里因为有透明度的变化,但它只是在滑动时才具有的,点击时不需要,不然会有很糟糕的视觉效果!!!同学可以试一下。
这里给出完整代码:
xml中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.xjf.wxswitchdemo.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="8dp"
></android.support.v4.view.ViewPager>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#888"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="8dp" />
<LinearLayout
android:layout_width="match_parent"
android:gravity="center"
android:orientation="horizontal"
android:layout_height="55dp">
<RelativeLayout
android:id="@+id/rl_home"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/home_normal" />
<ImageView
android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/home_selected" />
<TextView
android:layout_centerHorizontal="true"
android:layout_below="@+id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="微信"
/>
<TextView
android:textColor="#46c01b"
android:id="@+id/home_tv"
android:layout_centerHorizontal="true"
android:layout_below="@+id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="微信"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_category"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/category_normal" />
<ImageView
android:id="@+id/category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/category_selected" />
<TextView
android:layout_centerHorizontal="true"
android:layout_below="@+id/category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="通讯录"
/>
<TextView
android:textColor="#46c01b"
android:id="@+id/category_tv"
android:layout_centerHorizontal="true"
android:layout_below="@+id/category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="通讯录"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_service"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/service_normal" />
<ImageView
android:id="@+id/service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/service_selected" />
<TextView
android:layout_centerHorizontal="true"
android:layout_below="@+id/service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="发现"
/>
<TextView
android:textColor="#46c01b"
android:id="@+id/service_tv"
android:layout_centerHorizontal="true"
android:layout_below="@+id/service"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="发现"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_mine"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<!--正常显示时的图片-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/mine_normal" />
<!--选中时的图片-->
<ImageView
android:id="@+id/mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@mipmap/mine_selected" />
<!--正常显示的文字颜色-->
<TextView
android:layout_centerHorizontal="true"
android:layout_below="@+id/mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="我"
/>
<!--选中时显示的文字颜色-->
<TextView
android:textColor="#46c01b"
android:id="@+id/mine_tv"
android:layout_centerHorizontal="true"
android:layout_below="@+id/mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="我"
/>
</RelativeLayout>
</LinearLayout></LinearLayout>
MainActivity中代码:
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
@BindView(R.id.viewPager)
ViewPager viewPager;//ViewPager
@BindView(R.id.home)
ImageView home;//绿色的微信图片
@BindView(R.id.home_tv)
TextView homeTv;//绿色的微信问题
@BindView(R.id.rl_home)
RelativeLayout rlHome;
@BindView(R.id.category)
ImageView category;//绿色的通讯录图片
@BindView(R.id.category_tv)
TextView categoryTv;//绿色的通讯录文字
@BindView(R.id.rl_category)
RelativeLayout rlCategory;
@BindView(R.id.service)
ImageView service;//绿色的发现图片
@BindView(R.id.service_tv)
TextView serviceTv;//绿色的发现文字
@BindView(R.id.rl_service)
RelativeLayout rlService;
@BindView(R.id.mine)
ImageView mine;//绿色的我图片
@BindView(R.id.mine_tv)
TextView mineTv;//绿色的我文字
@BindView(R.id.rl_mine)
RelativeLayout rlMine;
private MyPagerAdapter adapter;//适配器
private List<Fragment> mTabs = new ArrayList<>();//Fragment集合
private List<ImageView> images = new ArrayList<>();//绿色图片集合
private List<TextView> texts = new ArrayList<>();//绿色文字集合
private String[] mContents = new String[]{"微信", "通讯录", "发现", "我"};//Fragment中TextView显示内容
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
viewPager.setAdapter(adapter = new MyPagerAdapter(getSupportFragmentManager()));
viewPager.setOnPageChangeListener(this);
}
private void initData() {
//创建TabFragment
for (int i = 0; i < mContents.length; i++) {
TabFragment tabFragment = new TabFragment();
Bundle bundle = new Bundle();
bundle.putString("content", mContents[i]);
tabFragment.setArguments(bundle);
mTabs.add(tabFragment);
}
images.add(home);
images.add(category);
images.add(service);
images.add(mine);
texts.add(homeTv);
texts.add(categoryTv);
texts.add(serviceTv);
texts.add(mineTv);
setselectedTabColor(0);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
changeAlpha(position, positionOffset);
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 0:
setselectedTabColor(0);
break;
case 1:
setselectedTabColor(1);
break;
case 2:
setselectedTabColor(2);
break;
case 3:
setselectedTabColor(3);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
private void changeAlpha(int pos, float posOffset) {
int nextIndex = pos + 1;
if (posOffset > 0) {
//设置tab的颜色渐变效果
images.get(pos).setAlpha(1f - posOffset);
images.get(nextIndex).setAlpha(posOffset);
texts.get(pos).setAlpha(1f-posOffset);
texts.get(nextIndex).setAlpha(posOffset);
}
}
;
private void setselectedTabColor(int pos) {
images.get(0).setAlpha(0f);
images.get(1).setAlpha(0f);
images.get(2).setAlpha(0f);
images.get(3).setAlpha(0f);
texts.get(0).setAlpha(0f);
texts.get(1).setAlpha(0f);
texts.get(2).setAlpha(0f);
texts.get(3).setAlpha(0f);
images.get(pos).setAlpha(1f);
texts.get(pos).setAlpha(1f);
}
private class MyPagerAdapter extends FragmentPagerAdapter {
//构造方法
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
//返回当前Fragment
@Override
public Fragment getItem(int position) {
return mTabs.get(position);
}
//返回Fragment个数
@Override
public int getCount() {
return mTabs.size();
}
}
@OnClick({R.id.rl_home, R.id.rl_category, R.id.rl_service, R.id.rl_mine})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.rl_home:
viewPager.setCurrentItem(0, false);
setselectedTabColor(0);
break;
case R.id.rl_category:
viewPager.setCurrentItem(1, false);
setselectedTabColor(1);
break;
case R.id.rl_service:
viewPager.setCurrentItem(2, false);
setselectedTabColor(2);
break;
case R.id.rl_mine:
viewPager.setCurrentItem(3, false);
setselectedTabColor(3);
break;
}
}}
你以为这样就结束了吗?不是这样的,装逼还没有结束。
接下来我们自定义一个透明度自动变化的Tab容器控件!!!没错,其实思路和之前类似,只不过是自定义控件而已。那么我们就直接开始干了!!!!!!!!!!!!!
首先是定义一个透明度可以改变的ImageView;
public class TabIconView extends ImageView{
private Paint mPaint;
//选中时bitmap
private Bitmap mSelectedIcon;
//正常状态下bitmap
private Bitmap mNormalIcon;
//focus bitmap矩阵
private Rect mSelectedRect;
// normal bitmap矩阵
private Rect mNormalRect;
/** 当前选择项(mSelectedIcon)透明度
* mNormalIcon透明度即为 255 - mSelectedAlpha*/
private int mSelectedAlpha = 0;
public TabIconView(Context context) {
this(context,null);
}
public TabIconView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public TabIconView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 初始化资源图片bitmap及相关绘制对象
* @param normal
* @param selected
* @param width
* @param height
*/
public final void init(int normal,int selected,int width,int height){
this.mNormalIcon = BitmapFactory.decodeResource(getResources(),normal);
this.mSelectedIcon = BitmapFactory.decodeResource(getResources(),selected);
this.mNormalRect = new Rect(0,0,width,height);
this.mSelectedRect = new Rect(0,0,width,height);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//设置画笔抗锯齿
};
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mPaint==null){
return;
}
mPaint.setAlpha(255-this.mSelectedAlpha);
canvas.drawBitmap(mNormalIcon,null,mNormalRect,mPaint);
mPaint.setAlpha(mSelectedAlpha);
canvas.drawBitmap(mSelectedIcon,null,mSelectedRect,mPaint);
}
/**
* 改变透明度
* @param alpha
*/
public final void changeSelectedAlpha(int alpha){
mSelectedAlpha = alpha;
invalidate();
}
/**
* 改变透明度百分比
* @param offset 百分比
*/
public final void offsetChanged(float offset) {
changeSelectedAlpha((int) (255 * (1 - offset)));
}}
接下来撸一个Tab容器。
public class TabContainerView extends LinearLayout {
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
/** 默认颜色*/
private int mTextNormalColor;
/** 选中时颜色值*/
private int mTextSelectedColor;
/** 前一次选择位置*/
private int mLastPosition;
/** 当前选中位置*/
private int mSelectedPosition;
/**选择偏移位置 */
private float mSelectionOffset;
/** tab 标题*/
private String[] mTitles;
/** tab icon集合*/
private int[][] mIconRes;
/** tab item 视图集合*/
private View[] mTabView;
/** 布局文件id*/
private int mLayoutId;
/** textView 控件id*/
private int mTextViewId;
/** icon 控件id*/
private int mIconVIewId;
/**icon宽度*/
private int mIconWidth;
/**icon高度*/
private int mIconHeight;
/** 是否显示过渡颜色效果*/
private boolean mShowTransitionColor = true;
public TabContainerView(Context context) {
this(context, null);
}
public TabContainerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void initContainer (String[] titles, int[][] iconsRes, int[] colors, boolean showTransitionColor) {
this.mTitles = titles;
this.mIconRes = iconsRes;
this.mTextNormalColor = getResources().getColor(colors[0]);
this.mTextSelectedColor = getResources().getColor(colors[1]);
this.mShowTransitionColor = showTransitionColor;
}
/**
* 设置布局文件及相关控件id
* @param layout layout布局文件 id
* @param iconId ImageView 控件 id id <=0 时不显示
* @param textId TextView 控件 id id <=0 时不显示
* @param width icon 宽度
* @param height icon 高度
*/
public void setContainerLayout (int layout, int iconId, int textId, int width, int height) {
mLayoutId = layout;
mTextViewId = textId;
mIconVIewId = iconId;
mIconWidth = width;
mIconHeight = height;
}
/**
* <p>设置布局文件及相关控件id --只有文本</p>
* @param layout layout布局文件 id
* @param textId TextView 控件 id
* @param width icon 宽度
* @param height icon 高度
*/
public void setSingleTextLayout (int layout, int textId, int width, int height) {
setContainerLayout(layout, 0, textId, width, height);
}
/**
* <p>设置布局文件及相关控件id</p>
* @param layout layout布局文件 id
* @param iconId ImageView 控件 id
* @param width icon 宽度
* @param height icon 高度
*/
public void setSingleIconLayout (int layout, int iconId, int width, int height) {
setContainerLayout(layout, iconId, 0, width, height);
}
public void setViewPager(ViewPager viewPager) {
removeAllViews();
mViewPager = viewPager;
if (viewPager != null && viewPager.getAdapter() != null) {
viewPager.addOnPageChangeListener(new InternalViewPagerListener());
addTabViewToContainer();
}
}
/**
* <p>添加tab view到当前容器</p>
*/
private void addTabViewToContainer() {
final PagerAdapter adapter = mViewPager.getAdapter();
mTabView = new View[adapter.getCount()];
for (int index = 0, len = adapter.getCount(); index < len; index++) {
final View tabView = LayoutInflater.from(getContext()).inflate(mLayoutId, this, false);
mTabView[index] = tabView;
/*tabIconView初始化*/
TabIconView iconView = null;
if (mIconVIewId > 0) {
iconView = (TabIconView) tabView.findViewById(mIconVIewId);
iconView.init(mIconRes[index][0], mIconRes[index][1], mIconWidth, mIconHeight);
}
/*tabTextView初始化*/
TextView textView = null;
if (mTextViewId > 0) {
textView = (TextView) tabView.findViewById(mTextViewId);
textView.setText(mTitles[index]);
}
/*设置宽度,等分container*/
LayoutParams lp = (LayoutParams) tabView.getLayoutParams();
lp.width = 0;
lp.weight = 1;
/*添加tab点击事件*/
addTabOnClickListener(tabView, index);
/*设置当前状态*/
if (index == mViewPager.getCurrentItem()) {
if (iconView != null) {
iconView.offsetChanged(0);
}
tabView.setSelected(true);
if (textView != null) {
textView.setTextColor(mTextSelectedColor);
}
}
addView(tabView);
}
}
/**
* <p>viewPager滑动改变监听事件</p>
*/
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
private int mScrollState;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
onViewPagerPageChanged(position, positionOffset);
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
/*完成滑动动作后更新每个Item TextView的颜色值以及ImageView的状态值*/
for (int i = 0; i < getChildCount(); i++) {
if (mIconVIewId > 0) {
((TabIconView) mTabView[i].findViewById(mIconVIewId)) .offsetChanged(position == i ? 0 : 1);
}
if (mTextViewId > 0) {
((TextView) mTabView[i].findViewById(mTextViewId)) .setTextColor(position == i ? mTextSelectedColor : mTextNormalColor);
}
}
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
onViewPagerPageChanged(position, 0f);
}
for (int i = 0, size = getChildCount(); i < size; i++) {
getChildAt(i).setSelected(position == i);
}
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageSelected(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
}
}
}
/**
* viewpager滑动改变后更新当前container视图
* @param position 当前选择position
* @param positionOffset position 偏移量
*/
private void onViewPagerPageChanged(int position, float positionOffset) {
mSelectedPosition = position;
mSelectionOffset = positionOffset;
if (positionOffset == 0f && mLastPosition != mSelectedPosition) {
mLastPosition = mSelectedPosition;
}
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final int childCount = getChildCount();
if (childCount > 0) {
/*当发生偏移时,绘制渐变区域*/
if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1) && mShowTransitionColor) {
/*获取当前tab和下一tab view */
View selectedTab = getChildAt(mSelectedPosition);
View nextTab = getChildAt(mSelectedPosition + 1);
/*显示tab icon时,刷新各自view 透明度*/
if (mIconVIewId > 0) {
View selectedIconView = selectedTab.findViewById(mIconVIewId);
View nextIconView = nextTab.findViewById(mIconVIewId);
//draw icon alpha
if (selectedIconView instanceof TabIconView && nextIconView instanceof TabIconView) {
((TabIconView) selectedIconView).offsetChanged(mSelectionOffset);
((TabIconView) nextIconView).offsetChanged(1 - mSelectionOffset);
}
}
/*显示tab text,刷新各自view 透明度*/
if (mTextViewId > 0) {
View selectedTextView = selectedTab.findViewById(mTextViewId);
View nextTextView = nextTab.findViewById(mTextViewId);
//draw text color
Integer selectedColor = (Integer) evaluate(mSelectionOffset, mTextSelectedColor, mTextNormalColor);
Integer nextColor = (Integer) evaluate(1 - mSelectionOffset, mTextSelectedColor, mTextNormalColor);
if (selectedTextView instanceof TextView && nextTextView instanceof TextView) {
((TextView) selectedTextView).setTextColor(selectedColor);
((TextView) nextTextView).setTextColor(nextColor);
}
}
}
}
}
/**
* tab item点击事件,点击时直接跳到对应view
* @param view View
* @param position position
*/
private void addTabOnClickListener (View view, final int position) {
OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
mViewPager.setCurrentItem(position, false);
}
};
view.setOnClickListener(listener);
}
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mViewPagerPageChangeListener = listener;
}
/**
* This function returns the calculated in-between value for a color
* given integers that represent the start and end values in the four
* bytes of the 32-bit int. Each channel is separately linearly interpolated
* and the resulting calculated values are recombined into the return value.
*
* @param fraction The fraction from the starting to the ending values
* @param startValue A 32-bit int value representing colors in the
* separate bytes of the parameter
* @param endValue A 32-bit int value representing colors in the
* separate bytes of the parameter
* @return A value that is calculated to be the linearly interpolated
* result, derived by separating the start and end values into separate
* color channels and interpolating each one separately, recombining the
* resulting values in the same way.
*/
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (startA + (int)(fraction * (endA - startA))) << 24 |
(startR + (int)(fraction * (endR - startR))) << 16 |
(startG + (int)(fraction * (endG - startG))) << 8 |
(startB + (int)(fraction * (endB - startB)));
}
public int getTextSelectedColor() {
return mTextSelectedColor;
}
public void setTextSelectedColor(int textSelectedColor) {
mTextSelectedColor = textSelectedColor;
}
public int getTextNormalColor() {
return mTextNormalColor;
}
public void setTextNormalColor(int textNormalColor) {
mTextNormalColor = textNormalColor;
}
public int getLastPosition() {
return mLastPosition;
}
public void setLastPosition(int lastPosition) {
mLastPosition = lastPosition;
}
public int getSelectedPosition() {
return mSelectedPosition;
}
public void setSelectedPosition(int selectedPosition) {
mSelectedPosition = selectedPosition;
}
public float getSelectionOffset() {
return mSelectionOffset;
}
public void setSelectionOffset(float selectionOffset) {
mSelectionOffset = selectionOffset;
}
public String[] getTitles() {
return mTitles;
}
public void setTitles(String[] titles) {
mTitles = titles;
}
public int[][] getIconRes() {
return mIconRes;
}
public void setIconRes(int[][] iconRes) {
mIconRes = iconRes;
}
public View[] getTabView() {
return mTabView;
}
public void setTabView(View[] tabView) {
mTabView = tabView;
}
public boolean isShowTransitionColor() {
return mShowTransitionColor;
}
public void setShowTransitionColor(boolean showTransitionColor) {
mShowTransitionColor = showTransitionColor;
}}
卧槽,不知不觉撸了这么多了,不过也完成了,接下来我们就直接拿着用好了。
首先我们编写一个tab_container_view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@null">
<com.example.xjf.wxswitchdemo.TabIconView
android:id="@+id/iv_tab_icon"
android:layout_marginTop="3dp"
android:layout_width="@dimen/tab_icon_width"
android:layout_height="@dimen/tab_icon_height"
android:layout_centerHorizontal="true"
android:scaleType="centerInside" />
<TextView
android:id="@+id/tv_tab_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:layout_below="@+id/iv_tab_icon"
android:textColor="@color/main_bottom_tab_textcolor_normal"
/></RelativeLayout>
接下来就是activity的xml了,也比较简单,直接引用我们自定义的TabContainerView就好了
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/tab_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#999999"></View>
<com.example.xjf.wxswitchdemo.TabContainerView
android:id="@+id/ll_tab_container"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white" /></LinearLayout>
最后再我们的Activity中完成数据的初始化操作和简单的切换即可。
public class Activity_Two extends AppCompatActivity implements ViewPager.OnPageChangeListener{
@BindView(R.id.tab_pager)
ViewPager tabPager;
@BindView(R.id.ll_tab_container)
TabContainerView llTabContainer;
private List<Fragment> mTabs = new ArrayList<>();//Fragment集合
private MyPagerAdapter adapter;//适配器
private final int ICONS_RES[][] = {
{
R.mipmap.home_normal,
R.mipmap.home_selected
},
{
R.mipmap.category_normal,
R.mipmap.category_selected
},
{
R.mipmap.service_normal,
R.mipmap.service_selected
},
{
R.mipmap.mine_normal,
R.mipmap.mine_selected
}
};
/** tab 颜色值*/
private final int[] TAB_COLORS = new int []{
R.color.main_bottom_tab_textcolor_normal,
R.color.main_bottom_tab_textcolor_selected};
private String[] mContents = new String[]{"微信", "通讯录", "发现", "我"};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_);
ButterKnife.bind(this);
initView();
}
private void initView(){
for (int i = 0; i < mContents.length; i++) {
TabFragment tabFragment = new TabFragment();
Bundle bundle = new Bundle();
bundle.putString("content", mContents[i]);
tabFragment.setArguments(bundle);
mTabs.add(tabFragment);
}
tabPager.setAdapter(adapter = new MyPagerAdapter(getSupportFragmentManager()));
TabContainerView mTabLayout = (TabContainerView) findViewById(R.id.ll_tab_container);
mTabLayout.setOnPageChangeListener(this);
mTabLayout.initContainer(mContents, ICONS_RES, TAB_COLORS, true);
int width = getResources().getDimensionPixelSize(R.dimen.tab_icon_width);
int height = getResources().getDimensionPixelSize(R.dimen.tab_icon_height);
mTabLayout.setContainerLayout(R.layout.tab_container_view, R.id.iv_tab_icon, R.id.tv_tab_text, width, height);
mTabLayout.setViewPager(tabPager);
tabPager.setCurrentItem(0);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
for (int index = 0, len = mTabs.size(); index < len; index ++) {
mTabs.get(position).onHiddenChanged(index != position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
private class MyPagerAdapter extends FragmentPagerAdapter {
//构造方法
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
//返回当前Fragment
@Override
public Fragment getItem(int position) {
return mTabs.get(position);
}
//返回Fragment个数
@Override
public int getCount() {
return mTabs.size();
}
}}
图片资源共享一下:
各位下期再见!!!!!
最后录制一张自己实现的效果图吧: