ViewPagerTabs,绘制tab底部线条长度小于文字

代码为android联系人中源码:


  ViewPager mPager;
  private ViewPagerTabStrip mTabStrip;

  /**
   * Linearlayout that will contain the TextViews serving as tabs. This is the only child
   * of the parent HorizontalScrollView.
   */
  final int mTextStyle;
  final ColorStateList mTextColor;
  final int mTextSize;
  final boolean mTextAllCaps;
  int mPrevSelected = -1;
  int mSidePadding;
  int mUnderlineColor;
  int mUnderlineThickness;

  private static final int TAB_SIDE_PADDING_IN_DPS = 10;


  /**
   * Simulates actionbar tab behavior by showing a toast with the tab title when long clicked.
   */
  private class OnTabLongClickListener implements OnLongClickListener {
      final int mPosition;

      public OnTabLongClickListener(int position) {
          mPosition = position;
      }

      @Override
      public boolean onLongClick(View v) {
          final int[] screenPos = new int[2];
          getLocationOnScreen(screenPos);

          final Context context = getContext();
          final int width = getWidth();
          final int height = getHeight();
          final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;

          Toast toast = Toast.makeText(context, mPager.getAdapter().getPageTitle(mPosition),
                  Toast.LENGTH_SHORT);

          // Show the toast under the tab
          toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL,
                  (screenPos[0] + width / 2) - screenWidth / 2, screenPos[1] + height);

          toast.show();
          return true;
      }
  }

  public ViewPagerTabs(Context context) {
      this(context, null);
  }

  public ViewPagerTabs(Context context, AttributeSet attrs) {
      this(context, attrs, 0);
  }

  public ViewPagerTabs(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      setFillViewport(true);

      mSidePadding = (int) (getResources().getDisplayMetrics().density * TAB_SIDE_PADDING_IN_DPS);

      final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerTabs,defStyle,0);
      mTextSize = a.getDimensionPixelSize(R.styleable.ViewPagerTabs_textSize, 0);
      mTextStyle = a.getInt(R.styleable.ViewPagerTabs_textStyle, 0);
      mTextColor = a.getColorStateList(R.styleable.ViewPagerTabs_textColor);
      mTextAllCaps = a.getBoolean(R.styleable.ViewPagerTabs_textAllCap, false);
      mUnderlineColor = a.getColor(R.styleable.ViewPagerTabs_underlineColor,0);
      mUnderlineThickness = a.getDimensionPixelOffset(R.styleable.ViewPagerTabs_underlineThickness,dp2px(2f));

      mTabStrip = new ViewPagerTabStrip(context);
      mTabStrip.setUnderlineColor(mUnderlineColor);
      mTabStrip.setSelectedUnderlineThickness(mUnderlineThickness);

      addView(mTabStrip,
              new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
      a.recycle();
  }

  public void setViewPager(ViewPager viewPager) {
      mPager = viewPager;
      addTabs(mPager.getAdapter());
      mPager.addOnPageChangeListener(this);
  }

  private void addTabs(PagerAdapter adapter) {
      mTabStrip.removeAllViews();

      final int count = adapter.getCount();
      for (int i = 0; i < count; i++) {
          addTab(adapter.getPageTitle(i), i);
      }
  }

  private void addTab(CharSequence tabTitle, final int position) {
      final TextView textView = new TextView(getContext());
      textView.setText(tabTitle);
      textView.setBackgroundResource(R.drawable.view_pager_tab_background);
      textView.setGravity(Gravity.CENTER);
      textView.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
              mPager.setCurrentItem(getRtlPosition(position));
          }
      });

      textView.setOnLongClickListener(new OnTabLongClickListener(position));

      // Assign various text appearance related attributes to child views.
      if (mTextStyle > 0) {
          textView.setTypeface(textView.getTypeface(), mTextStyle);
      }
      if (mTextSize > 0) {
          textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
      }
      if (mTextColor != null) {
          textView.setTextColor(mTextColor);
      }
      textView.setAllCaps(mTextAllCaps);
      textView.setPadding(mSidePadding, 0, mSidePadding, 0);
      mTabStrip.addView(textView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
              LayoutParams.MATCH_PARENT, 1));
      // Default to the first child being selected
      if (position == 0) {
          mPrevSelected = 0;
          textView.setSelected(true);
      }
  }

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
      position = getRtlPosition(position);
      int tabStripChildCount = mTabStrip.getChildCount();
      if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
          return;
      }
      mTabStrip.onPageScrolled(position, positionOffset, positionOffsetPixels);
      if(null != onPageChangeListener){
          onPageChangeListener.onPageScrolled(position,positionOffset,positionOffsetPixels);
      }
  }

  @Override
  public void onPageSelected(int position) {
      position = getRtlPosition(position);
      if (mPrevSelected >= 0) {
          mTabStrip.getChildAt(mPrevSelected).setSelected(false);
      }
      final View selectedChild = mTabStrip.getChildAt(position);
      selectedChild.setSelected(true);

      // Update scroll position
      final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2;
      smoothScrollTo(scrollPos, 0);
      mPrevSelected = position;
      if(null != onPageChangeListener){
          onPageChangeListener.onPageSelected(position);
      }
  }

  @Override
  public void onPageScrollStateChanged(int state) {
      if(null != onPageChangeListener){
          onPageChangeListener.onPageSelected(state);
      }
  }

  private int getRtlPosition(int position) {
      if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
          return mTabStrip.getChildCount() - 1 - position;
      }
      return position;
  }

  private int dp2px(float dpVal){
      return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
              dpVal, getContext().getResources().getDisplayMetrics());
  }

  private OnPageChangeListener onPageChangeListener;

  public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener){
      this.onPageChangeListener = onPageChangeListener;
  }

  public interface OnPageChangeListener{
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
      public void onPageSelected(int position);
      public void onPageScrollStateChanged(int state);
  }

}

ViewPagerTabStrip.java:

public class ViewPagerTabStrip extends LinearLayout {
    private int mSelectedUnderlineThickness;
    private final Paint mSelectedUnderlinePaint;

    private int mIndexForSelection;
    private float mSelectionOffset;
    private int mUnderlineColor;
    private int mBackgroundColor;

    public ViewPagerTabStrip(Context context) {
        this(context, null);
    }

    public ViewPagerTabStrip(Context context, AttributeSet attrs) {
        super(context, attrs);

        final Resources res = context.getResources();

        mSelectedUnderlineThickness =
                res.getDimensionPixelSize(R.dimen.tab_selected_underline_height);
        mUnderlineColor = res.getColor(R.color.tab_selected_underline_color);
        mBackgroundColor = res.getColor(R.color.actionbar_background_color);

        mSelectedUnderlinePaint = new Paint();
        mSelectedUnderlinePaint.setColor(mUnderlineColor);

        setBackgroundColor(mBackgroundColor);
        setWillNotDraw(false);
    }

    @Override
    public void setBackgroundColor(int color) {
        super.setBackgroundColor(color);
    }

    public void setUnderlineColor(int underlineColor){
        mUnderlineColor = underlineColor;
        mSelectedUnderlinePaint.setColor(mUnderlineColor);
    }

    public void setSelectedUnderlineThickness(int size){
        mSelectedUnderlineThickness = size;
    }

    /**
     * Notifies this view that view pager has been scrolled. We save the tab index
     * and selection offset for interpolating the position and width of selection
     * underline.
     */
    void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        mIndexForSelection = position;
        mSelectionOffset = positionOffset;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int childCount = getChildCount();

        // Thick colored underline below the current selection
        if (childCount > 0) {
            View selectedTitle = getChildAt(mIndexForSelection);
            int selectedLeft = selectedTitle.getLeft();
            int selectedRight = selectedTitle.getRight();
            final boolean isRtl = isRtl();
            final boolean hasNextTab = isRtl ? mIndexForSelection > 0
                    : (mIndexForSelection < (getChildCount() - 1));
            if ((mSelectionOffset > 0.0f) && hasNextTab) {
                // Draw the selection partway between the tabs
                View nextTitle = getChildAt(mIndexForSelection + (isRtl ? -1 : 1));
                int nextLeft = nextTitle.getLeft();
                int nextRight = nextTitle.getRight();

                selectedLeft = (int) (mSelectionOffset * nextLeft +
                        (1.0f - mSelectionOffset) * selectedLeft);
                selectedRight = (int) (mSelectionOffset * nextRight +
                        (1.0f - mSelectionOffset) * selectedRight);
            }

            int height = getHeight();
            canvas.drawRect(selectedLeft, height - mSelectedUnderlineThickness,
                    selectedRight, height, mSelectedUnderlinePaint);
        }
    }

    private boolean isRtl() {
        return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
    }

使用:

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        List mFragmentList = new ArrayList<>();
        mAfragment = new Afragment();
        mFragmentList.add(0,Afragment);
        mFragmentList.add(1, new Bfragment());
        mFragmentList.add(2, new Cfragment());

        TabFragmentPageAdapter pageAdapter = new     
        TabFragmentPageAdapter(getSupportFragmentManager(),mFragmentList);
        ViewPager viewPager = findViewById(R.id.vp_game);
        viewPager.setAdapter(pageAdapter);
        final ViewPagerTabs mViewPagerTabs = findViewById(R.id.view_tab);
        mViewPagerTabs.setViewPager(viewPager);

        addOnPageChangeListener(mViewPagerTabs);
        viewPager.setCurrentItem(0);
        viewPager.setOffscreenPageLimit(3);
        viewPager.addOnPageChangeListener(this);
        
    }
  public void addOnPageChangeListener(ViewPager.OnPageChangeListener           
    onPageChangeListener) {
        if (!mOnPageChangeListeners.contains(onPageChangeListener)) {
            mOnPageChangeListeners.add(onPageChangeListener);
        }
    }

private ArrayList mOnPageChangeListeners =
            new ArrayList();


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        final int count = mOnPageChangeListeners.size();
        for (int i = 0; i < count; i++) {
            mOnPageChangeListeners.get(i).onPageScrolled(position, positionOffset,
                    positionOffsetPixels);
        }
    }

    @Override
    public void onPageSelected(int position) {
        final int count = mOnPageChangeListeners.size();
        for (int i = 0; i < count; i++) {
            mOnPageChangeListeners.get(i).onPageSelected(position);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        final int count = mOnPageChangeListeners.size();
        for (int i = 0; i < count; i++) {
            mOnPageChangeListeners.get(i).onPageScrollStateChanged(state);
        }
    }

你可能感兴趣的:(ViewPagerTabs,绘制tab底部线条长度小于文字)