打造自己的 PagerSlidingTabStrip 之三 (ViewPager 切换时 Tab 颜色渐变)

前言

在 打造自己的 PagerSlidingTabStrip 之二 (选中后 Tab 变色) 中,我们实现了给 PagerSlidingTabStrip 添加滑动时 Tab 颜色改变的效果,当然颜色切换太过生硬,所以我们再进行优化下,实现知乎的 ViewPager 页面的效果。

效果图

知乎效果:

效果图

效果图

我们实现的效果:

效果图

效果图

分析

首先来看下知乎的效果图,滑动 ViewPager 时,顶部的 Tab 颜色会随之渐变,被选中 Tab 的颜色会比其他 Tab 的颜色更深,并且被选中和将被选中的 Tab 的颜色根据 ViewPager 滑动的位移有渐变的效果。

上一章中我们实现了给 Tab 添加滑动变色效果,但是只实现了滑动时颜色的改变,我们注意在 ViewPager 的滑动监听 OnPageChangeListener 接口中有个回调方法 onPageScrolled 会返回一个参数 positionOffset,给我们提供页面的偏移量,根据这个偏移量,我们可以手动改变 Tab 的颜色。

//positionOffset 为偏移量
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

代码及解析

根据上面的分析,我们可以通过偏移量改变来设置 Tab 的颜色。那么我们首先要修改下 updateTabColor() 方法。

//这里的 value 为偏移量
private void updateTabColor(View tabView, float value) {
    if (tabType == TAB_TYPE_TEXT) {
        updateTextViewColor(tabView, value);
    } else {
        updateImageButtonAlpha(tabView, value);
    }
}

对应的我们要修改 updateTextViewColor() 方法和 updateImageButtonAlpha 方法,这里我们更改 TextView 颜色的方法是通过偏移量计算出对应的透明度,然后通过 Color.arb(int alpha, int red, int green, int blue) 方法获取到对应的颜色后,设置到 TextView 中,代码如下:

//更新所有 TextView 文字颜色
  private void updateTextViewColor(View tabView, float currentPositionOffset) {
  //currentAlpha 为透明度, currentAlpha = 255 时,颜色为不透明,默认为 155
      int currentAlpha = (int)(155 + currentPositionOffset * 100);
      if (tabView instanceof TextView) {
          ((TextView) tabView).setTextColor(Color.argb(currentAlpha, Color.red(tabTextColor), Color.green(tabTextColor), Color.blue(tabTextColor)));
      } else if (tabView instanceof FrameLayout
              && ((FrameLayout) tabView).getChildAt(0) instanceof TextView) {
          ((TextView) ((FrameLayout) tabView).getChildAt(0)).setTextColor(Color.argb(currentAlpha, Color.red(tabTextColor), Color.green(tabTextColor), Color.blue(tabTextColor)));
      }
  }

设置 ImageButton 的透明度就相对容易一些了,只要获取到要设置的透明度就可以了,代码如下:

private void updateImageButtonAlpha(View tabView, float currentPositionOffset) {
  int alphaInteger = (int)(155 + currentPositionOffset * 100);
  float alpha = 0.5f + currentPositionOffset * 0.5f;

  if(tabView instanceof ImageButton) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      tabView.setAlpha(alpha);
    } else {
      ((ImageButton)tabView).setAlpha(alphaInteger);
    }
  } else if (tabView instanceof FrameLayout
    && ((FrameLayout) tabView).getChildAt(0) instanceof ImageButton) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      ((FrameLayout) tabView).getChildAt(0).setAlpha(alpha);
    } else {
      ((ImageButton) ((FrameLayout) tabView).getChildAt(0)).setAlpha(alphaInteger);
    }
  }
}

最近想把知乎的所有效果尽量实现一下,因为知乎告诉我:认真你就赢了。

最后,项目 Github 地址 ,欢迎 Star ^-^