自定义ViewPagerIndicator三角形指示器、圆形指示器简单使用

添加命名空间

xmlns:qishui="http://schemas.android.com/apk/res-auto"

使用控件布局

<com.example.zhou.tabpageindicator.view.ViewPagerIndicator
    android:id="@+id/id_indicator"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    android:background="@color/colorPrimary"
    android:orientation="horizontal"
    qishui:item_count="5">
</com.example.zhou.tabpageindicator.view.ViewPagerIndicator>
<android.support.v4.view.ViewPager
    android:id="@+id/id_vp"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">
</android.support.v4.view.ViewPager>

逻辑设置

final List<String> mDatas = Arrays.asList(UiUtils.getStringArray(R.array.tab_names));
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
    @Override
    public int getCount() {
        return mDatas.size();
    }

    @Override
    public Fragment getItem(int position) {
        return FragmentFactory.createFragment(position);
    }
};
//设置Tab上的标题
mIndicator.setTabItemTitles(mDatas);
mViewPager.setAdapter(mAdapter);
//设置关联的ViewPager
mIndicator.setViewPager(mViewPager, 0);

其中mDatas获取到的是一串在Strings.xml字符集合

<string-array name="tab_names">
    <item>首页</item>
    <item>活动</item>
    <item>辅练</item>
    <item>商城</item>
    <item>我的</item>
</string-array>

简单点可以直接定义出来,不必获取xml中的;其中FragmentFactory就是创建不同的fragment简单点new 一个定义好的即可。

此文只为记录,向hongyang大佬致敬

http://blog.csdn.net/lmj623565791/article/details/42160391

相关资料下载

http://pan.baidu.com/s/1slFbxF3

 

圆形指示器

public class CircleIndicatorView extends View implements ViewPager.OnPageChangeListener{
    private static final String LETTER[] = new String[]{"A","B","C","D","E","F","G","H","I","G","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
    // private int mSelectColor = Color.parseColor("#E38A7C");
    private int mSelectColor = Color.parseColor("#FFFFFF");
    private Paint mCirclePaint;
    private Paint mTextPaint;
    private int mCount; // indicator 的数量
    private int mRadius;//半径
    private int mStrokeWidth;//border
    private int mTextColor;// 小圆点中文字的颜色
    private int mDotNormalColor;// 小圆点默认颜色
    private int mSpace = 0;// 圆点之间的间距
    private List<Indicator> mIndicators;
    private int mSelectPosition = 0; // 选中的位置
    private FillMode mFillMode = FillMode.NONE;// 默认只有小圆点
    private ViewPager mViewPager;
    private OnIndicatorClickListener mOnIndicatorClickListener;
    /**
     * 是否允许点击Indicator切换ViewPager
     */
    private boolean mIsEnableClickSwitch = false;
    public CircleIndicatorView(Context context) {
        super(context);
        init();
    }

    public CircleIndicatorView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        getAttr(context,attrs);
        init();
    }

    public CircleIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getAttr(context,attrs);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CircleIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        getAttr(context,attrs);
        init();
    }

    private void init(){

        mCirclePaint = new Paint();
        mCirclePaint.setDither(true);
        mCirclePaint.setAntiAlias(true);
        mCirclePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        mTextPaint = new Paint();
        mTextPaint.setDither(true);
        mTextPaint.setAntiAlias(true);
        // 默认值
        mIndicators = new ArrayList<>();

        initValue();

    }

    private void initValue(){
        mCirclePaint.setColor(mDotNormalColor);
        mCirclePaint.setStrokeWidth(mStrokeWidth);

        mTextPaint.setColor(mTextColor);
        mTextPaint.setTextSize(mRadius);
    }

    /**
     * 获取自定义属性
     * @param context
     * @param attrs
     */
    private void getAttr(Context context,AttributeSet attrs){
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleIndicatorView);
        mRadius = (int) typedArray.getDimensionPixelSize(R.styleable.CircleIndicatorView_indicatorRadius,dpToPx(6));
        mStrokeWidth = (int) typedArray.getDimensionPixelSize(R.styleable.CircleIndicatorView_indicatorBorderWidth,dpToPx(2));
        mSpace = typedArray.getDimensionPixelSize(R.styleable.CircleIndicatorView_indicatorSpace,dpToPx(5));
        // color
        mTextColor = typedArray.getColor(R.styleable.CircleIndicatorView_indicatorTextColor,Color.BLACK);
        mSelectColor = typedArray.getColor(R.styleable.CircleIndicatorView_indicatorSelectColor,Color.WHITE);
        mDotNormalColor = typedArray.getColor(R.styleable.CircleIndicatorView_indicatorColor,Color.GRAY);

        mIsEnableClickSwitch = typedArray.getBoolean(R.styleable.CircleIndicatorView_enableIndicatorSwitch,false);
        int fillMode = typedArray.getInt(R.styleable.CircleIndicatorView_fill_mode,2);
        if(fillMode == 0){
            mFillMode = FillMode.LETTER;
        }else if(fillMode == 1){
            mFillMode = FillMode.NUMBER;
        }else{
            mFillMode = FillMode.NONE;
        }
        typedArray.recycle();
    }

    /**
     * 测量每个圆点的位置
     */
    private void measureIndicator(){
        mIndicators.clear();
        float cx = 0;
        for(int i=0;i<mCount;i++){
            Indicator indicator = new Indicator();
            if( i== 0){
                cx = mRadius + mStrokeWidth;
            }else{
                cx += (mRadius + mStrokeWidth) * 2 +mSpace;
            }

            indicator.cx = cx;
            indicator.cy = getMeasuredHeight() / 2;

            mIndicators.add(indicator);
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int width = (mRadius+mStrokeWidth)* 2 * mCount + mSpace *(mCount - 1);
        int height = mRadius * 2 + mSpace * 2;

        setMeasuredDimension(width,height);

        measureIndicator();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        for(int i=0;i<mIndicators.size();i++){

            Indicator indicator = mIndicators.get(i);
            float x = indicator.cx;

            float y = indicator.cy;

            if(mSelectPosition == i){
                mCirclePaint.setStyle(Paint.Style.FILL);
                mCirclePaint.setColor(mSelectColor);
            }else{
                mCirclePaint.setColor(mDotNormalColor);
                if(mFillMode != FillMode.NONE){
                    mCirclePaint.setStyle(Paint.Style.STROKE);
                }else{
                    mCirclePaint.setStyle(Paint.Style.FILL);

                }
            }
            canvas.drawCircle(x,y, mRadius, mCirclePaint);

            // 绘制小圆点中的内容
            if(mFillMode != FillMode.NONE){
                String text = "";
                if(mFillMode == FillMode.LETTER){
                    if(i >= 0 && i<LETTER.length){
                        text = LETTER[i];
                    }
                }else{
                    text = String.valueOf(i+1);
                }
                Rect bound = new Rect();
                mTextPaint.getTextBounds(text,0,text.length(),bound);
                int textWidth = bound.width();
                int textHeight = bound.height();

                float textStartX = x - textWidth / 2;
                float textStartY = y + textHeight / 2;
                canvas.drawText(text,textStartX,textStartY, mTextPaint);
            }

        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float xPoint = 0;
        float yPoint = 0;
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                xPoint = event.getX();
                yPoint = event.getY();
                handleActionDown(xPoint,yPoint);
                break;

        }

        return super.onTouchEvent(event);
    }

    private void handleActionDown(float xDis,float yDis){
        for(int i=0;i<mIndicators.size();i++){
            Indicator indicator = mIndicators.get(i);
            if(xDis < (indicator.cx + mRadius+mStrokeWidth)
                    && xDis >=(indicator.cx - (mRadius + mStrokeWidth))
                    && yDis >= (yDis - (indicator.cy+mStrokeWidth))
                    && yDis <(indicator.cy+mRadius+mStrokeWidth)){
                // 找到了点击的Indicator
                // 是否允许切换ViewPager
                if(mIsEnableClickSwitch){
                    mViewPager.setCurrentItem(i,false);
                }

                // 回调
                if(mOnIndicatorClickListener!=null){
                    mOnIndicatorClickListener.onSelected(i);
                }
                break;
            }
        }
    }

    public void setOnIndicatorClickListener(OnIndicatorClickListener onIndicatorClickListener) {
        mOnIndicatorClickListener = onIndicatorClickListener;
    }

    private void setCount(int count) {
        mCount = count;
        invalidate();
    }

    /**
     * 设置 border
     * @param borderWidth
     */
    public void setBorderWidth(int borderWidth){
        mStrokeWidth = borderWidth;
        initValue();
    }

    /**
     * 设置文字的颜色
     * @param textColor
     */
    public void setTextColor(int textColor) {
        mTextColor = textColor;
        initValue();
    }

    /**
     * 设置选中指示器的颜色
     * @param selectColor
     */
    public void setSelectColor(int selectColor) {
        mSelectColor = selectColor;
    }

    /**
     *  设置指示器默认颜色
     * @param dotNormalColor
     */
    public void setDotNormalColor(int dotNormalColor) {
        mDotNormalColor = dotNormalColor;
        initValue();
    }

    /**
     * 设置选中的位置
     * @param selectPosition
     */
    public void setSelectPosition(int selectPosition) {
        mSelectPosition = selectPosition;
    }

    /**
     * 设置Indicator 模式
     * @param fillMode
     */
    public void setFillMode(FillMode fillMode) {
        mFillMode = fillMode;
    }

    /**
     * 设置Indicator 半径
     * @param radius
     */
    public void setRadius(int radius) {
        mRadius = radius;
        initValue();
    }

    public void setSpace(int space) {
        mSpace = space;
    }

    public void setEnableClickSwitch(boolean enableClickSwitch){
        mIsEnableClickSwitch = enableClickSwitch;
    }
    /**
     *  与ViewPager 关联
     * @param viewPager
     */
    public void setUpWithViewPager(ViewPager viewPager){
        releaseViewPager();
        if(viewPager == null){
            return;
        }
        mViewPager = viewPager;
        mViewPager.addOnPageChangeListener(this);
        int count = mViewPager.getAdapter().getCount();
        setCount(count);
    }

    /**
     * 重置ViewPager
     */
    private void releaseViewPager(){
        if(mViewPager!=null){
            mViewPager.removeOnPageChangeListener(this);
            mViewPager = null;
        }

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        mSelectPosition = position;
        invalidate();
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /**
     * Indicator 点击回调
     */
    public interface OnIndicatorClickListener{
        public void onSelected(int position);
    }


    public static class Indicator{
        public float cx; // 圆心x坐标
        public float cy; // 圆心y 坐标
    }

    public enum FillMode{
        LETTER,
        NUMBER,
        NONE
    }


    public  int dpToPx(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
    }

    public  int pxToDp(float px) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px, Resources.getSystem().getDisplayMetrics());
    }

}

自定义属性

<declare-styleable name="CircleIndicatorView">
    <attr name="indicatorRadius" format="dimension"/>
    <attr name="indicatorBorderWidth" format="dimension"/>
    <attr name="indicatorSpace" format="dimension"/>
    <attr name="indicatorTextColor" format="color"/>
    <attr name="indicatorColor" format="color"/>
    <attr name="indicatorSelectColor" format="color"/>
    <attr name="enableIndicatorSwitch" format="boolean"/>
    <attr name="fill_mode">
        <enum name="letter" value="0"/>
        <enum name="number" value="1"/>
        <enum name="none" value="2"/>
    </attr>
</declare-styleable>

xml设置

<com.zhouwei.indicatorview.CircleIndicatorView
         android:id="@+id/indicator_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:layout_marginBottom="50dp"
         android:layout_centerHorizontal="true"
         app:indicatorSelectColor="#00A882"
         app:fill_mode="letter"
         app:indicatorBorderWidth="2dp"
         app:indicatorRadius="8dp"
         app:indicatorColor="@color/colorAccent"
         app:indicatorTextColor="@android:color/white"
         />

.class设置

// 初始化ViewPager 相关
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mPagerAdapter = new ViewPagerAdapter();
        mViewPager.setAdapter(mPagerAdapter);

        mIndicatorView = (CircleIndicatorView) findViewById(R.id.indicator_view);
        // 关联ViewPager 
        mIndicatorView.setUpWithViewPager(mViewPager);

相关设置可以不在xml中设置,在代码中同样可以设置

// 在代码中设置相关属性
        
        CircleIndicatorView indicatorView = (CircleIndicatorView) findViewById(R.id.indicator_view3);
        // 设置半径
        indicatorView.setRadius(DisplayUtils.dpToPx(15));
        // 设置Border
        indicatorView.setBorderWidth(DisplayUtils.dpToPx(2));

        // 设置文字颜色
        indicatorView.setTextColor(Color.WHITE);
        // 设置选中颜色
        indicatorView.setSelectColor(Color.parseColor("#FEBB50"));
        //
        indicatorView.setDotNormalColor(Color.parseColor("#E38A7C"));
        // 设置指示器间距
        indicatorView.setSpace(DisplayUtils.dpToPx(10));
        // 设置模式
        indicatorView.setFillMode(CircleIndicatorView.FillMode.LETTER);
        
        // 设置点击Indicator可以切换ViewPager
        indicatorView.setEnableClickSwitch(true);

        // 最重要的一步:关联ViewPager
        indicatorView.setUpWithViewPager(mViewPager);

自定义属性

属性名属性意义取值
indicatorRadius设置指示器圆点的半径单位为 dp 的值
indicatorBorderWidth设置指示器的border单位为 dp 的值
indicatorSpace设置指示器之间的距离单位为 dp 的值
indicatorTextColor设置指示器中间的文字颜色颜色值,如:#FFFFFF
indicatorColor设置指示器圆点的颜色颜色值
indicatorSelectColor设置指示器选中的颜色颜色值
fill_mode设置指示器的模式枚举值:有三种,分别是letter,number和none
enableIndicatorSwitch设置是否点击Indicator切换ViewPager,默认为false布尔值

源代码参见

https://github.com/pinguo-zhouwei/CircleIndicatorView

 

 

转载于:https://my.oschina.net/u/3015461/blog/916382

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值