ScrollingTabs

自定义ScrollingTabs结合ViewPager实现指引的效果。
image

原理:
由于ScrollingTabs即可以点击又可以实现左右滑动,首先想到的就是继承HorizontalScrollView来实现滑动,至于点击的实现需要通过对View 设置点击。
通过对ViewPager设置OnPageChangeListener来监听页面变化,从而实现对ScrollingTabs的改变,而在每个Tab上设置 点击事件,当点击的时候就去设置ViewPager的当前页面

  1. 继承HorizontalScrollView,并且添加一个水平方向的线性布局,作为Tab的父布局

     public class ScrollingTabs extends HorizontalScrollView {
    
         private LinearLayout mContainer;
    
         public ScrollingTabs(Context context, AttributeSet attrs, int defStyle) {
             super(context, attrs, defStyle);
             init(context);
         }
    
         public ScrollingTabs(Context context, AttributeSet attrs) {
             super(context, attrs);
             init(context);
         }
    
         public ScrollingTabs(Context context) {
             super(context);
             init(context);
         }
    
         private void init(Context context) {
             this.setHorizontalScrollBarEnabled(false);
             this.setHorizontalFadingEdgeEnabled(false);
    
             mContainer = new LinearLayout(context);
             LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                     android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                     android.view.ViewGroup.LayoutParams.MATCH_PARENT);
             mContainer.setLayoutParams(params);
             mContainer.setOrientation(LinearLayout.HORIZONTAL);
    
             addView(mContainer);
         }
     }
    
  2. 提供接口供调用者设置每个Tab的视图。

     public interface TabAdapter {
         /**
          * 每个Tab的视图
          */
         public View getView(int position);
         /**
          * Tab之间的分割线
          */
         public View getSeparator();
     }
    
  3. 暴露方法,初始化Tab。

     public void setTabAdapter(TabAdapter adapter) {
         this.mTabAdapter = adapter;
         initTabView();
     }
    
     public void setViewPager(ViewPager pager) {
         this.mViewPager = pager;
         mViewPager.setOnPageChangeListener(this);
         initTabView();
     }
    
     /**
      * 必须等到ViewPager和TabAdapter都设置完成后才可以调用
      */
     private void initTabView() {
         if (mViewPager != null && mTabAdapter != null) {
             //清空父布局,保险起见
             mContainer.removeAllViews();
             //根据ViewPager的页数去设置Tab
             for (int i = 0; i < mViewPager.getAdapter().getCount(); i++) {
                 final View tab = mTabAdapter.getView(i);
                 tab.setTag(i);
    
                 mContainer.addView(tab);
    
                 // Segmentation view
                 if (mTabAdapter.getSeparator() != null
                         && i != mViewPager.getAdapter().getCount() - 1) {
                     //Tabs之间使用分割线
                     isUseSeperator = true;
                     mContainer.addView(mTabAdapter.getSeparator());
                 }
    
                 // 对每个Tab设置点击事件
                 tab.setOnClickListener(new OnClickListener() {
    
                     @Override
                     public void onClick(View v) {
                         int index = (Integer) tab.getTag();
                         if (mTabClickListener != null) {
                             //暴露接口
                             mTabClickListener.onClick(index);
                         } else {
                             if (mViewPager.getCurrentItem() == index) {
                                 //如果当前ViewPager已经显示到了该Tab也,就直接让其选中
                                 selectTab(index);
                             } else {
                                 //当前ViewPager并没有显示该Tab页,要让ViewPager去显示相应的Tab页
                                 mViewPager.setCurrentItem(index, true);
                             }
                         }
                     }
                 });
    
             }
    
             // 初始化时核对一下Tab
             selectTab(mViewPager.getCurrentItem());
         }
     }
    
  4. selectTab的实现,选中相应的Tab,并且实现滑动到屏幕中间位置

     private void selectTab(int position) {
         if (!isUseSeperator) {
             //没有分割线
             for (int i = 0; i < mContainer.getChildCount(); i++) {
                 View tab = mContainer.getChildAt(i);
                 tab.setSelected(i == position);
             }
         } else {
             //有分割线
             for (int i = 0, pos = 0; i < mContainer.getChildCount(); i += 2, pos++) {
                 View tab = mContainer.getChildAt(i);
                 tab.setSelected(pos == position);
             }
         }
         //得到当前的Tab
         View selectedView = null;
         if (!isUseSeperator) {
             selectedView = mContainer.getChildAt(position);
         } else {
             selectedView = mContainer.getChildAt(position * 2);
         }
    
         int tabWidth = selectedView.getMeasuredWidth();
         int tabLeft = selectedView.getLeft();
    
         //距离左边屏幕的位置加上该Tab宽度的一半正好是该Tab中心点的位置。我们需要让该Tab的中心点移动到屏幕的中心点。
         int distance = (tabLeft + tabWidth / 2) - mWindowWidth / 2;
         //移动
         smoothScrollTo(distance, this.getScrollY());
     }
    

results matching ""

    No results matching ""