撸一个微信的底部Tab切换透明度变化效果

微信6.0的时候就出现有了底部Tab切换透明度变化的效果,趁着周末也抽空来实现一下,其实十分简单,我们先来看一下效果:

撸一个微信的底部Tab切换透明度变化效果_第1张图片

嗯,没错,又是偷的图

原图来自:http://upload-images.jianshu.io/upload_images/2552605-8cf01f84f3a344d3?imageMogr2/auto-orient/strip
效果大概就跟上图一模一样吧。,所以我就懒得自己录制了。
首先我们拿到这一个需求,操起我们的笔和纸,将你知道的一些用于实现的思路写下来,要养成一个良好的习惯哦。

撸一个微信的底部Tab切换透明度变化效果_第2张图片

解剖后大概能知道:1,ViewPager和Fragment结合使用(此处用FragmentPagerAdapter)
2,可能需要两套图,选中状态套餐A(就是那个绿帽子颜色的),未选中时的套餐B(被绿后世界都变成灰色了)
3,需要动态的获取position以及positionOffset,然后拿到左右两个View,设置positionOffset (这个值时关键!!!);
4,处理点击时图片文字切换
哇靠,原来就这么简单。

撸一个微信的底部Tab切换透明度变化效果_第3张图片

那么这里最骚的操作在哪里呢,就是重中之重的第三步操作了!!
有些同学可能会疑问positionOffset是什么,怎么用?

撸一个微信的底部Tab切换透明度变化效果_第4张图片

这里给大家简单通过一道数学题目来解释一下,我们大家都解过方程式吧,such as:y=1-x;我们画个图,大概长这样:

撸一个微信的底部Tab切换透明度变化效果_第5张图片

y随着x的递增而减小。

其实我们的滑动处理和这个函数的一模一样的,我们当前选中项的绿色透明度为1,下一个Tab的值为0(Y),positionOffset的值即为X。


撸一个微信的底部Tab切换透明度变化效果_第6张图片

好的,本文分析到此结束!

撸一个微信的底部Tab切换透明度变化效果_第7张图片

同学可以下课自己实现了

我也偷偷打开我的Android studio实现了一波:

首先我们看xml代码,我们需要在xml中通过相对布局或者FramLayout来将绿色图套在灰色图之上!!!(因为无论透明度如何发现改变,只是针对绿色图片,我!们!底!部!的!灰!色!图!片!一!直!都!在!)。

我们每个tab都应该时这样处理的,这里给出一个,另外三个是一样的。文末给出完整代码

           

        
        
        
        
        
        
        
        
    
撸一个微信的底部Tab切换透明度变化效果_第8张图片
xml分界线,接下来是Java了

接下来好戏登场了,我们开始编写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 mTabs = new ArrayList<>();//Fragment集合
private List images = new ArrayList<>();//绿色图片集合
private List 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滑动时的动画效果,我们这里因为有透明度的变化,但它只是在滑动时才具有的,点击时不需要,不然会有很糟糕的视觉效果!!!同学可以试一下。

撸一个微信的底部Tab切换透明度变化效果_第9张图片
完成了,喝杯啤酒,兄弟

这里给出完整代码:
xml中:









    

        

        

        

        

    

    
        

        

        

        
    

    

        

        

        

        
    

    

        
        
        
        
        
        
        
        
    


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 mTabs = new ArrayList<>();//Fragment集合
private List images = new ArrayList<>();//绿色图片集合
private List 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切换透明度变化效果_第10张图片

接下来我们自定义一个透明度自动变化的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;
}

/**
 * 

设置布局文件及相关控件id --只有文本

* @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); } /** *

设置布局文件及相关控件id

* @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(); } } /** *

添加tab view到当前容器

*/ 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); } } /** *

viewPager滑动改变监听事件

*/ 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切换透明度变化效果_第11张图片

首先我们编写一个tab_container_view:

 




接下来就是activity的xml了,也比较简单,直接引用我们自定义的TabContainerView就好了








最后再我们的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 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();
    }
}}
撸一个微信的底部Tab切换透明度变化效果_第12张图片
到此结束

图片资源共享一下:

mine_selected.png

service_selected.png

category_selected.png

category_normal.png

home_normal.png

home_selected.png

mine_normal.png

各位下期再见!!!!!

撸一个微信的底部Tab切换透明度变化效果_第13张图片

最后录制一张自己实现的效果图吧:

撸一个微信的底部Tab切换透明度变化效果_第14张图片

你可能感兴趣的:(撸一个微信的底部Tab切换透明度变化效果)