效果图
步骤
- 继承HorizontalScrollView
- 初始化必要属性与类
- 暴露方法 setTabDatum 根据数据 来创建tab
- 绑定ViewPager 根据ViewPager.setOnPageChangeListener来处理我们画Tab下划线的逻辑
- 在dispatchDraw中画线
实现
- 继承HorizontalScrollView
public class ViewPagerIndicator extends HorizontalScrollView
- 初始化必要属性与类
public ViewPagerIndicator(Context context) {
this(context, null);
}
public ViewPagerIndicator(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContainer = new LinearLayout(context);
mContainer.setOrientation(LinearLayout.HORIZONTAL);
addView(mContainer);
init();
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(mTabLineColor);
}
public int getScreenWidth() {
WindowManager wm = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}
- 暴露方法 setTabDatum 根据数据 来创建tab
// /****************** about tab *****************/
/**
* 2. set tab datum in ViewPagerIndicator
* @param datum
*/
public void setTabDatum(List<String> datum) {
if (datum == null || datum.size() <= 0) {
return;
}
mContainer.removeAllViews();
mTabCount = datum.size();
for (int i = 0; i < datum.size(); i++) {
TextView view = createTab(datum.get(i));
mContainer.addView(view);
setTabClickListener(i, view);
}
}
private void setTabClickListener(final int finalI, View view) {
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mViewPager != null) {
mViewPager.setCurrentItem(finalI);
}
}
});
}
private TextView createTab(String text) {
TextView tv = new TextView(getContext());
LayoutParams lp = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.width = mTabWidth;
tv.setGravity(Gravity.CENTER);
tv.setTextColor(mTabTextColor);
tv.setText(text);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTabTextSize);
tv.setLayoutParams(lp);
tv.setBackgroundColor(mTabBackgroundColor);
return tv;
}
void resetAllTab() {
for (int i = 0; i < mTabCount; i++) {
View child = mContainer.getChildAt(i);
if (child instanceof TextView) {
((TextView) child).setTextColor(mTabTextColor);
}
}
}
void setTabSelected(int position) {
resetAllTab();
View child = mContainer.getChildAt(position);
if (child instanceof TextView) {
((TextView) child).setTextColor(mTabTextSelectedColor);
}
}
- 绑定ViewPager 根据ViewPager.setOnPageChangeListener来处理我们画Tab下划线的逻辑
///******************* about callback *******************/
interface PageChangeListener {
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
void onPageSelected(int position);
void onPageScrollStateChanged(int state);}
private PageChangeListener onPageChangeListener;
public void setOnPageChangeListener(PageChangeListener onPageChangeListener) {
this.onPageChangeListener = onPageChangeListener;
}
/**
* 1. bind ViewPager and set tab's position
* @param viewPager
* @param pos
*/
public void bindViewPager(ViewPager viewPager, int pos) {
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
updateLine(position, positionOffset);
if (onPageChangeListener != null) {
onPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
setTabSelected(position);
if (onPageChangeListener != null) {
onPageChangeListener.onPageSelected(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
if (onPageChangeListener != null) {
onPageChangeListener.onPageScrollStateChanged(state);
}
}
});
setTabSelected(pos);
mViewPager.setCurrentItem(pos);
}
private void updateLine(int position, float positionOffset) {
mTranslationX = (int) (getWidth() / mTabVisibleCount * (position + positionOffset));
if (positionOffset > 0 && position >= (mTabVisibleCount - 2)
&& mContainer.getChildCount() > mTabVisibleCount) {
if (mTabVisibleCount != 1) {
this.scrollTo((int) ((position - (mTabVisibleCount - 2)) * mTabWidth
+ (int) (mTabWidth * positionOffset)), 0);
} else {
this.scrollTo(
position * mTabWidth + (int) (mTabWidth * positionOffset), 0);
}
}
invalidate();
}
- 在dispatchDraw中画线
// /****************** about tab line *****************/
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
Rect rect = new Rect(
//if it does not set lineWidth
mTranslationX +
(mLineWidth == 0 ? 0 : mTabWidth / 2 - mLineWidth / 2),
getMeasuredHeight() - mLineHeight,
//if it does not set lineWidth
mTranslationX +
(mLineWidth == 0 ? mTabWidth : mTabWidth / 2 + mLineWidth / 2),
getMeasuredHeight());
canvas.drawRect(rect, mPaint);
}
具体使用
mViewPagerIndicator = (ViewPagerIndicator) findViewById(R.id.vpi_container);
mViewPager = (ViewPager) findViewById(R.id.vp_container);
// 1. bind ViewPager and set tab's position
mViewPagerIndicator.bindViewPager(mViewPager, 0);
// 2. set tab datum in ViewPagerIndicator
mViewPagerIndicator.setTabDatum(mDatum);
代码下载
https://github.com/agxxxx/ViewPagerIndicator
参考&&感谢
Hongyang 先生