自定义ViewGroup实现一个最简单的ViewPager指示器,还是写个文章记录下吧,没有什么难点
这里只是实现了一个跟随Viewpager的下划线效果,以这个为蓝本,可以去实现其他效果
绘制下划线
/**
* notify all subView to invalidate themselves,
* use this to draw a line show which tab selected.
*/
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
canvas.translate(mTranslationX, getHeight() - 2); // 移动canvas
canvas.drawLine(0, 0, mTabWidth, 0, mPaint); // 此时Canvas坐标已经发生变化
canvas.restore();
}
跟随滑动
/**
* let indicator smooth scroll. May be called by {@link android.support.v4.view.ViewPager
* #addOnPageChangeListener(ViewPager.OnPageChangeListener)}
*
* @param position current tab title index. 0~tabs.length
* @param offset the distant fraction between two tabs 0~1
*/
public void scroll(int position, float offset) {
mTranslationX = (int) (mWidth / mTabs.length * (position + offset));
invalidate();
}
生成Tab文本
/**
* generate tab textView.
*/
private void generateTabText() {
if (getChildCount() > 0) {
removeAllViews();
}
int count = mTabs.length;
// set weight for all View.
setWeightSum(count);
for (int i = 0; i < count; i++) {
TextView textView = new TextView(mContext);
LinearLayout.LayoutParams params = new LayoutParams(0
, ViewGroup.LayoutParams.MATCH_PARENT);
params.weight = 1;
textView.setText(mTabs[i]);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.BLACK);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
textView.setLayoutParams(params);
textView.setTag(i);
textView.setPadding(DEFAULT_TAB_PADDING
, DEFAULT_TAB_PADDING, DEFAULT_TAB_PADDING, DEFAULT_TAB_PADDING); // pixels
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mTitleClickListener != null) {
int index = (int) v.getTag();
mTitleClickListener.onTitleClick(v, index);
}
}
});
addView(textView);
}
}
全部代码
/**
* Created by shixi_tianrui1 on 16-10-24.
* a simple indicator for viewPager. Just a demo.
*/
public class MyIndicator extends LinearLayout {
private static final String TAG = "MyIndicator";
private Context mContext;
private Paint mPaint;
private int mWidth;
private int mHeight;
private String[] mTabs;
private int mTabWidth;
private int mTranslationX; // the translation X for canvas.
private final static int DEFAULT_INDICATOR_COLOR = Color.BLUE;
private final static int DEFAULT_INDICATOR_WIDTH = 10; // pixels
private final static int DEFAULT_TAB_PADDING = 5; // pixels
private OnTitleClickListener mTitleClickListener;
interface OnTitleClickListener {
void onTitleClick(View view, int index);
}
public MyIndicator(Context context) {
this(context, null);
}
public MyIndicator(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(DEFAULT_INDICATOR_WIDTH);
mPaint.setColor(DEFAULT_INDICATOR_COLOR);
setOrientation(HORIZONTAL);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
mTabWidth = mWidth / mTabs.length;
}
/**
* add listener for this tab, each tabView clicked would callback this method.
*
* @param listener listener for each tabView.
*/
public void setOnTitleClickListener(OnTitleClickListener listener) {
this.mTitleClickListener = listener;
}
/**
* set this tab titles.
*/
public void setTitles(String[] tabs) {
mTabs = tabs;
generateTabText();
}
/**
* generate tab textView.
*/
private void generateTabText() {
if (getChildCount() > 0) {
removeAllViews();
}
int count = mTabs.length;
// set weight for all View.
setWeightSum(count);
for (int i = 0; i < count; i++) {
TextView textView = new TextView(mContext);
LinearLayout.LayoutParams params = new LayoutParams(0
, ViewGroup.LayoutParams.MATCH_PARENT);
params.weight = 1;
textView.setText(mTabs[i]);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.BLACK);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
textView.setLayoutParams(params);
textView.setTag(i);
textView.setPadding(DEFAULT_TAB_PADDING
, DEFAULT_TAB_PADDING, DEFAULT_TAB_PADDING, DEFAULT_TAB_PADDING); // pixels
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mTitleClickListener != null) {
int index = (int) v.getTag();
mTitleClickListener.onTitleClick(v, index);
}
}
});
addView(textView);
}
}
/**
* notify all subView to invalidate themselves,
* use this to draw a line show which tab selected.
*/
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
canvas.translate(mTranslationX, getHeight() - 2); // 移动canvas
canvas.drawLine(0, 0, mTabWidth, 0, mPaint); // 此时Canvas坐标已经发生变化
canvas.restore();
}
/**
* let indicator smooth scroll. May be called by {@link android.support.v4.view.ViewPager
* #addOnPageChangeListener(ViewPager.OnPageChangeListener)}
*
* @param position current tab title index. 0~tabs.length
* @param offset the distant fraction between two tabs 0~1
*/
public void scroll(int position, float offset) {
mTranslationX = (int) (mWidth / mTabs.length * (position + offset));
invalidate();
}
}