Android 教你打造炫酷的ViewPagerIndicator 不仅仅是高(5)

这里注意下,我们不是把setOnPageChangeListener用了么,但是用户可能也需要监听这个接口,去干一些事,那么我们就需要给用户解决,于是我们自己定义一个类似的接口公布给用户:

/**
  * 对外的ViewPager的回调接口
  *
  * @author zhy
  *
  */
 public interface PageChangeListener
 {
  public void onPageScrolled(int position, float positionOffset,
    int positionOffsetPixels);

public void onPageSelected(int position);

public void onPageScrollStateChanged(int state);
 }

// 对外的ViewPager的回调接口
 private PageChangeListener onPageChangeListener;

// 对外的ViewPager的回调接口的设置
 public void setOnPageChangeListener(PageChangeListener pageChangeListener)
 {
  this.onPageChangeListener = pageChangeListener;
 }

如果用户需要回调,请使用我们的mIndicator.setOnPageChangeListener,回调的方法和原本的listener一模一样~~ 

ps:不要问我,这里用了mViewPager.setOnPageChangeListener我还想监听咋办,以及我设置了mViewPager.setOnPageChangeListener指示器怎么不动了,请仔细看上文

当然了,还有个高亮文本和重置文本颜色的代码,其实就是简单改变下当前选择的Tab的文本的颜色。

/**
  * 高亮文本
  *
  * @param position
  */
 protected void highLightTextView(int position)
 {
  View view = getChildAt(position);
  if (view instanceof TextView)
  {
   ((TextView) view).setTextColor(COLOR_TEXT_HIGHLIGHTCOLOR);
  }

}

/**
  * 重置文本颜色
  */
 private void resetTextViewColor()
 {
  for (int i = 0; i < getChildCount(); i++)
  {
   View view = getChildAt(i);
   if (view instanceof TextView)
   {
    ((TextView) view).setTextColor(COLOR_TEXT_NORMAL);
   }
  }
 }

接下来就到scroll登场了~ 

6、scroll

/**
  * 指示器跟随手指滚动,以及容器滚动
  *
  * @param position
  * @param offset
  */
 public void scroll(int position, float offset)
 {
  /**
  * <pre>
  *  0-1:position=0 ;1-0:postion=0;
  * </pre>
  */
  // 不断改变偏移量,invalidate
  mTranslationX = getWidth() / mTabVisibleCount * (position + offset);

int tabWidth = getScreenWidth() / mTabVisibleCount;

// 容器滚动,当移动到倒数最后一个的时候,开始滚动
  if (offset > 0 && position >= (mTabVisibleCount - 2)
    && getChildCount() > mTabVisibleCount)
  {
   if (mTabVisibleCount != 1)
   {
    this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth
      + (int) (tabWidth * offset), 0);
   } else
   // 为count为1时 的特殊处理
   {
    this.scrollTo(
      position * tabWidth + (int) (tabWidth * offset), 0);
   }
  }

invalidate();
 }

看完之后,有没有一种,卧槽,就这几行代码就实现了,指示器跟随滚动和我们的Tab跟随滚动~~

嗯,其实指示器跟随滚动上面说了,依赖mTranslationX,然后借着canvas.translate实现的~~也就是说,就一行去确定当前应该的偏移即可。

比如:从第0个Tab滑向第1个Tab:position为0,offset会0.0~1.0这么变化~我们的偏移量实际也就是增加 offset * 每个Tab的宽度~

好了,下面说容器滚动,其实容器滚动的x也是 offset * 每个Tab的宽度~;只不过,有个前提就是当前滑动的是可见的倒数第二个到最后一个,所以我们有个判断:

position >= (mTabVisibleCount - 2) ; 于是乎,我们在偏移的时候也有:(position - (mTabVisibleCount - 2)) * tabWidth ;如当前恰好是可见的倒数第二个到最后一个,

那么position - (mTabVisibleCount - 2)为0,偏移量也就是(tabWidth * offset)~~

当可见为0的时候,我们需要特殊处理下,也就是我们的else~

最后记得invalidate~~

好了,到此核心的方法介绍完了~~剩下些杂七杂八的~~

7、剩余的方法

/**
  * 设置可见的tab的数量
  *
  * @param count
  */
 public void setVisibleTabCount(int count)
 {
  this.mTabVisibleCount = count;
 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/222f759a6ae386cedcb36c8bdc618a39.html