Android 自定义控件之圆点指示器 View (IndicateDotView)

来源:互联网 发布:windows api编程 编辑:程序博客网 时间:2024/06/07 14:03

转载请标明出处: http://blog.csdn.net/airsaid/article/details/52904344
本文出自:周游的博客

前言

最近公司项目中,有一个如下的UI:
这里写图片描述
可以看到,右侧的圆点,虽然可以直接用布局实现,但是由于很多地方都出现了,所以考虑到复用性不高。可以直接用自定义View来实现,扩展性和复用性都很好,并且这个View也很简单,直接画圆就行了。

最终效果

这里写图片描述

代码

首先来定义需要用到的自定义属性:

<!--圆点指示器View属性--><declare-styleable name="IndicateDotView">    <!--已选中指示点颜色-->    <attr name="indicate_select_color" format="color"/>    <!--未选中指示点颜色-->    <attr name="indicate_unselect_color" format="color"/>    <!--指示点之间的间距-->    <attr name="indicate_margin" format="dimension"/>    <!--指示点半径-->    <attr name="indicate_radius" format="dimension"/>    <!--指示点被选中个数-->    <attr name="indicate_number" format="integer"/>    <!--指示点最大个数-->    <attr name="indicate_max_number" format="integer"/>    <!--是否最少保留一个指示点-->     <attr name="indicate_is_least_one" format="boolean"/>    <!--边框颜色-->    <attr name="indicate_divide_color" format="color"/>    <!--边框宽度-->    <attr name="indicate_divide_width" format="dimension"/>    <!--是否可点击-->    <attr name="android:clickable" /></declare-styleable>

在代码中获取:

public IndicateDotView(Context context, AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IndicateDotView);    mUnSelectColor = a.getColor(R.styleable.IndicateDotView_indicate_unselect_color, mUnSelectColor);    mSelectColor = a.getColor(R.styleable.IndicateDotView_indicate_select_color, mSelectColor);    mDivideWidth = (int) a.getDimension(R.styleable.IndicateDotView_indicate_divide_width, mDivideWidth);    mDivideColor = a.getColor(R.styleable.IndicateDotView_indicate_divide_color, mDivideColor);    mIsLeastOne = a.getBoolean(R.styleable.IndicateDotView_indicate_is_least_one, mIsLeastOne);    mMargin = (int) a.getDimension(R.styleable.IndicateDotView_indicate_margin, mMargin);    mRadius = (int) a.getDimension(R.styleable.IndicateDotView_indicate_radius, mRadius);    mClickable = a.getBoolean(R.styleable.IndicateDotView_android_clickable, mClickable);    mMaxNumber = a.getInt(R.styleable.IndicateDotView_indicate_max_number, mMaxNumber);    mNumber = a.getInt(R.styleable.IndicateDotView_indicate_number, mNumber);    a.recycle();    mPaint = new Paint();    mPaint.setAntiAlias(true);}

onDraw()中绘制:

@Overrideprotected void onDraw(Canvas canvas) {    if(mNumber > mMaxNumber){        if(mIsLeastOne){            mNumber = 1;        }else{            mNumber = 0;        }    }    for (int i = 0; i < mMaxNumber; i++) {        if(i < mNumber){            mPaint.setColor(mSelectColor);            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);            drawCircle(canvas, i);        }else{            mPaint.setColor(mUnSelectColor);            mPaint.setStyle(Paint.Style.FILL);            drawCircle(canvas, i);            if(mDivideColor != -1){                mPaint.setColor(mDivideColor);                mPaint.setStyle(Paint.Style.STROKE);                mPaint.setStrokeWidth(mDivideWidth);                drawCircle(canvas, i);            }        }    }}

代码很简单,就是根据最大圆点数循环绘制圆以及边框,绘制圆的代码如下:

private void drawCircle(Canvas canvas, int i){    canvas.drawCircle(getPaddingLeft() + mRadius + mDivideWidth + (((mRadius * 2)            + (mDivideWidth * 2) + mMargin) * i), getHeight() / 2, mRadius, mPaint);}

最后在onMeasure()计算宽高:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    int widthMode = MeasureSpec.getMode(widthMeasureSpec);    int heightMode = MeasureSpec.getMode(heightMeasureSpec);    int widthSize = MeasureSpec.getSize(widthMeasureSpec);    int heightSize = MeasureSpec.getSize(heightMeasureSpec);    int width = 0;    int height = 0;    if(widthMode != MeasureSpec.EXACTLY){        width = mMaxNumber * (mRadius * 2 + mDivideWidth * 2 + mMargin) + getPaddingLeft() + getPaddingRight();    }    if(heightMode != MeasureSpec.EXACTLY){        height = mRadius * 2 + mDivideWidth * 2 + getPaddingTop() + getPaddingBottom();    }    setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width,            heightMode == MeasureSpec.EXACTLY ? heightSize : height);}

源码下载

GitHub地址:https://github.com/Airsaid/IndicateDotView

0 0