Android 实现Viewpager指示器

自定义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();
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值