自定义圆形经验统计View

来源:互联网 发布:seo从入门到精通 编辑:程序博客网 时间:2024/06/07 03:16

自定义View是我们作为一个“猿”必要掌握的招数,下面介绍下招数。

1.首先在onMeasure方法中量测量View和它的内容来确定测量的宽度和高度。

onMeasure(int widthMeasureSpec, int heightMeasureSpec)

    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        // 获取视图宽高        mWidth = MeasureSpec.getSize(widthMeasureSpec);        mHeight = MeasureSpec.getSize(heightMeasureSpec);        // 取最小值        if (mWidth != mHeight) {            int mMin = Math.min(mWidth, mHeight);            mWidth = mMin;            mHeight = mMin;        }        setMeasuredDimension(mWidth, mHeight);    }
2.在onDraw方法中得到Canvas(画布)绘制图案

draw(Canvas canvas)

得到画布后先用画笔(Paint)画出对应的图案。

  @Override  public void draw(Canvas canvas) {      super.draw(canvas);      drawConfig(canvas);// 初始设置      drawCircle(canvas);// 绘制圆      drawScaleLine(canvas);// 绘制刻度线      drawIndicator(canvas);// 绘制光标      drawTitleText(canvas);// 绘制标题文本      drawContentText(canvas);// 绘制内容文本  }
3.效果图如下:


4.源码如下:
/** * 作者:僧格洛卓 * 描述:CircleProgressView */public class CircleProgressView extends View {    private Context mContext;    /**     * 视图宽高     */    private int mWidth, mHeight;    /**     * 画圆所在的距形区域     */    private RectF mRectF;    /**     * 画圆和刻度线     */    private Paint mPaint;    /**     * 画光标     */    private Paint mIndicatorPaint;    /**     * 圆线条粗细     */    private int mStrokeWidth = 5;    /**     * 进度圆线条粗细     */    private int mProgressLineWidth = 8;    /**     * 刻度线粗细     */    private int mScaleLineWidth = 2;    /**     * 进度     */    private float mProgress = 0;    /**     * 进度最大值,默认100     */    private float mMaxProgress = 100;    /**     * 线条颜色     */    private int mCircleLineColor;    /**     * 进度条颜色     */    private int mCircleProgressLineColor;    /**     * 圆弧线宽     */    private float mCircleBorderWidth;    /**     * 内边距     */    private float mCirclePadding;    /**     * 标题文本     */    private String mTitleText;    /**     * 内容文本     */    private String mContentText;    /**     * 标题文本大小     */    private int mTitleTextSize;    /**     * 内容文本大小     */    private int mContentTextSize;    /**     * 标题字体颜色     */    private int mTitleTextColor;    /**     * 内容字体颜色     */    private int mContentTextColor;    public CircleProgressView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init(context, attrs);    }    private void init(Context context, AttributeSet attrs) {        this.mContext = context;        mRectF = new RectF();        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        TypedArray mArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);        mCircleLineColor = mArray.getColor(R.styleable.CircleProgressView_circleLineColor, Color.parseColor("#D3D3D3"));        mCircleProgressLineColor = mArray.getColor(R.styleable.CircleProgressView_circleProgressLineColor, Color.parseColor("#FFFFFF"));        mCircleBorderWidth = mArray.getDimensionPixelSize(R.styleable.CircleProgressView_circleLineBorderWidth, dip2px(10));        mCirclePadding = mArray.getDimensionPixelSize(R.styleable.CircleProgressView_circleLinePadding, dip2px(5));        mTitleTextSize = mArray.getDimensionPixelSize(R.styleable.CircleProgressView_circleTitleTextSize, dip2px(20));        mContentTextSize = mArray.getDimensionPixelSize(R.styleable.CircleProgressView_circleContentTextSize, dip2px(20));        mTitleTextColor = mArray.getColor(R.styleable.CircleProgressView_circleTitleTextColor, Color.parseColor("#FFFFFF"));        mContentTextColor = mArray.getColor(R.styleable.CircleProgressView_circleContentTextColor, Color.parseColor("#FFFFFF"));        mArray.recycle();    }    /**     * 设置最大值     *     * @param maxProgress     */    public void setMaxProgress(float maxProgress) {        this.mMaxProgress = maxProgress;    }    /**     * 设置进度     *     * @param progress 进度值     */    public void setProgress(float progress) {        this.mProgress = progress;        invalidate();    }    /**     * 设置进度     *     * @param progress 进度值     * @param duration 动画时长     */    public void setProgress(float progress, long duration) {        setProgressAnimator(progress, duration);    }    /**     * 设置进度动画     *     * @param progress 进度值     * @param duration 动画持续时长     */    private void setProgressAnimator(float progress, long duration) {        float mDuration = ((mMaxProgress / duration) * progress) * 1000;        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, progress);        valueAnimator.setDuration((long) mDuration);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator valueAnimator) {                mProgress = (float) valueAnimator.getAnimatedValue();                invalidate();            }        });        valueAnimator.start();    }    /**     * 设置进度条线条粗细     *     * @param width     */    public void setProgressLineWidth(int width) {        this.mProgressLineWidth = width;    }    /**     * 设置刻度线线条粗细     *     * @param width     */    public void setScaleLineWidth(int width) {        this.mScaleLineWidth = width;    }    /**     * 设置底圆线条颜色     *     * @param color     */    public void setCircleLineColor(int color) {        this.mCircleLineColor = color;    }    /**     * 设置进度调线条颜色     *     * @param color     */    public void setCircleProgressLineColor(int color) {        this.mCircleProgressLineColor = color;    }    /**     * 设置刻度线外边距     *     * @param width     */    public void setCircleBorderWidth(float width) {        this.mCircleBorderWidth = width;    }    /**     * 设置刻度线内边距     *     * @param padding     */    public void setCirclePadding(float padding) {        this.mCirclePadding = padding;    }    /**     * 设置标题     *     * @param title     */    public void setTitleText(String title) {        this.mTitleText = title;    }    /**     * 设置标题字体颜色     *     * @param color     */    public void setTitleTextColor(int color) {        this.mTitleTextColor = color;    }    /**     * 标题字体大小     *     * @param size     */    public void setTitleTextSize(int size) {        this.mTitleTextSize = size;    }    /**     * 设置内容     *     * @param content     */    public void setContentText(String content) {        this.mContentText = content;    }    /**     * 设置内容字体颜色     *     * @param color     */    public void setContentTextColor(int color) {        this.mContentTextColor = color;    }    /**     * 内容字体大小     *     * @param size     */    public void setContentTextSize(int size) {        this.mContentTextSize = size;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        // 获取视图宽高        mWidth = MeasureSpec.getSize(widthMeasureSpec);        mHeight = MeasureSpec.getSize(heightMeasureSpec);        // 取最小值        if (mWidth != mHeight) {            int mMin = Math.min(mWidth, mHeight);            mWidth = mMin;            mHeight = mMin;        }        setMeasuredDimension(mWidth, mHeight);    }    @Override    public void draw(Canvas canvas) {        super.draw(canvas);        drawConfig(canvas);// 初始设置        drawCircle(canvas);// 绘制圆        drawScaleLine(canvas);// 绘制刻度线        drawIndicator(canvas);// 绘制光标        drawTitleText(canvas);// 绘制标题文本        drawContentText(canvas);// 绘制内容文本    }    /**     * 初始设置     */    private void drawConfig(Canvas canvas) {        mPaint.setAntiAlias(true);// 是否抗锯齿        canvas.drawColor(Color.TRANSPARENT); // 设置画布为透明        mPaint.setStyle(Paint.Style.STROKE);        // 位置        mRectF.left = 20; // 左上角X        mRectF.top = 20; // 左上角Y        mRectF.right = getWidth() - 20; // 右下角X        mRectF.bottom = getWidth() - 20; // 右下角Y    }    /**     * 绘制圆     *     * @param canvas     */    private void drawCircle(Canvas canvas) {        canvas.save();        // 绘制底层圆        mPaint.setStrokeWidth(mStrokeWidth);        mPaint.setColor(mCircleLineColor);        canvas.drawArc(mRectF, -90, 360, false, mPaint);        // 绘制进度圆        mPaint.setStrokeWidth(mProgressLineWidth);        mPaint.setColor(mCircleProgressLineColor);        canvas.drawArc(mRectF, -90, (mProgress / mMaxProgress) * 360, false, mPaint);        canvas.restore();    }    /**     * 绘制刻度线     *     * @param canvas     */    private void drawScaleLine(Canvas canvas) {        canvas.save();        //半径        float mRadius = (getMeasuredWidth() - mCirclePadding * 3) / 2 - mCirclePadding;        //X轴中点坐标        int mCenterX = getMeasuredWidth() / 2;        // 设置刻度线颜色        mPaint.setColor(mCircleLineColor);        mPaint.setStrokeWidth(mScaleLineWidth);        for (float i = 0; i < 360; i += 3.6) {            double mArc = i * Math.PI / 180;            float mStartX = (float) (mCenterX + (mRadius - mCircleBorderWidth) * Math.sin(mArc));            float mStartY = (float) (mCenterX + (mRadius - mCircleBorderWidth) * Math.cos(mArc));            float mStopX = (float) (mCenterX + mRadius * Math.sin(mArc) + 1);            float mStopY = (float) (mCenterX + mRadius * Math.cos(mArc) + 1);            canvas.drawLine(mStartX, mStartY, mStopX, mStopY, mPaint);        }        canvas.restore();    }    /**     * 绘制光标     *     * @param canvas     */    private void drawIndicator(Canvas canvas) {        canvas.save();        float mRadius = getMeasuredWidth() / 2 - 20;        // 计算从正上方旋转了多少度        float mArc = (mProgress / mMaxProgress) * 360;        // 计算圆弧上X,Y轴坐标        float mIndicatorX = mRectF.centerX() + (float) (mRadius * Math.cos(Math.toRadians(mArc + 270)));        float mIndicatorY = mRectF.centerY() + (float) (mRadius * Math.sin(Math.toRadians(mArc + 270)));        // 设置相关属性        mIndicatorPaint.setAntiAlias(true);        mIndicatorPaint.setStyle(Paint.Style.FILL);        mIndicatorPaint.setColor(mCircleProgressLineColor);        // 设置过滤器,设置模糊效果时需关闭硬件加速器        mIndicatorPaint.setMaskFilter(new BlurMaskFilter(dip2px(3), BlurMaskFilter.Blur.NORMAL));        canvas.drawCircle(mIndicatorX, mIndicatorY, dip2px(3), mIndicatorPaint);        canvas.restore();    }    /**     * 绘制标题文本     *     * @param canvas     */    private void drawTitleText(Canvas canvas) {        if (!TextUtils.isEmpty(mTitleText)) {            canvas.save();            mPaint.setColor(mTitleTextColor);            mPaint.setStyle(Paint.Style.FILL);            mPaint.setTextSize(mTitleTextSize);            int mTextHeight = mHeight / 4;            int mTextWidth = (int) mPaint.measureText(mTitleText, 0, mTitleText.length());            canvas.drawText(mTitleText, (mWidth / 2) - (mTextWidth / 2), (mHeight / 3) + (mTextHeight / 2), mPaint);            canvas.restore();        }    }    /**     * 绘制内容文本     *     * @param canvas     */    private void drawContentText(Canvas canvas) {        if (!TextUtils.isEmpty(mContentText)) {            canvas.save();            mPaint.setColor(mContentTextColor);            mPaint.setStyle(Paint.Style.FILL);            mPaint.setTextSize(mContentTextSize);            int mTextHeight = mHeight / 4;            int mTextWidth = (int) mPaint.measureText(mContentText, 0, mContentText.length());            canvas.drawText(mContentText, (mWidth / 2) - (mTextWidth / 2), ((mHeight / 4) + (mTextHeight / 2)) * 1.8F, mPaint);            canvas.restore();        }    }    public int dip2px(float dipValue) {        final float scale = mContext.getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    } }
3.自定义属性:
    <declare-styleable name="CircleProgressView">        <!--圆内刻度线宽度-->        <attr name="circleLineBorderWidth" format="reference|dimension|integer" />        <!--圆内刻度线内边距-->        <attr name="circleLinePadding" format="reference|dimension|integer" />        <!--线条颜色-->        <attr name="circleLineColor" format="reference|color" />        <!--进度条线条颜色-->        <attr name="circleProgressLineColor" format="reference|color" />        <!--标题文本字体大小-->        <attr name="circleTitleTextSize" format="reference|dimension|integer" />        <!--内容文字大小-->        <attr name="circleContentTextSize" format="reference|dimension|integer" />        <!--标题文本字体颜色-->        <attr name="circleTitleTextColor" format="reference|color" />        <!--内容文本字体颜色-->        <attr name="circleContentTextColor" format="reference|color" />    </declare-styleable>
5.在布局中使用
  <!-- 这里只对文本Size进行了设置,其他属性根据自己需求进行设置-->  <com.example.app.view.widget.CircleProgressView      android:layout_width="200dp"      android:layout_height="200dp"      circle:circleContentTextSize="25sp" />
6.在java代码中使用
  mProgress.setTitleText("No.1");  mProgress.setContentText("Super VIP");  mProgress.setMaxProgress(100);  mProgress.setProgress(60, 3000);
0 0
原创粉丝点击