自定义View之圆环进度条

最进在学自定义View,我还是一只菜鸟,今天就做一个自定义View的圆环进度条,话不多说,先上效果图
这里写图片描述

直接贴代码吧

package rxjava.application.com.rxjavaproject;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * @author Qiujc
 * created time at 2016/05/20
 */
public class LoadingView extends View {
    private Paint circlePaint; //背景圆环画笔
    private Paint progressPaint; //进度条圆环画笔
    private Paint mTextPaint;//数字画笔
    private int currentProgress = 0; //当前进度
    private float radius; // 圆的半径
    private int circleColor = Color.GRAY;
    private int progressColor = Color.parseColor("#E78018");
    private int mtextColor = Color.BLACK;
    private float circlePaintWith;
    private Context mContext;
    private int SrceenWidth;
    private int SrceenHeight;
    private float mTextWidth;
    private float mTextHeight;
    private int progressRoundColor = Color.BLUE;
    private int maxProgress = 100;
    private float progressWith;

    public LoadingView(Context context) {
        super(context);
        mContext = context;
        init(null, 0);
    }

    public LoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init(attrs, 0);
    }

    public LoadingView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {

        circlePaintWith = dp2Px(15);
        progressWith = dp2Px(15);
        radius = dp2Px(100);

        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(circleColor);
        circlePaint.setStrokeWidth(circlePaintWith);
        circlePaint.setStyle(Paint.Style.STROKE);

        progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(progressWith);
        progressPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setColor(mtextColor);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextWidth = mTextPaint.measureText(String.valueOf(currentProgress) + "%");

        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        mTextHeight = fontMetrics.bottom;
        mTextPaint.setTextSize(dp2Px(30));
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float circleX = SrceenWidth / 2.0f;
        float circleY = SrceenHeight / 2.0f;
        //先绘制背景圆环
        canvas.drawCircle(SrceenWidth / 2, SrceenHeight / 2, radius, circlePaint);
        //再绘制进度数字
        canvas.drawText(String.valueOf(currentProgress + "%"), SrceenWidth / 2, SrceenHeight / 2 + (mTextHeight), mTextPaint);

        RectF rect = new RectF(0, 0, 0, 0);
        float circleRealRadius = radius + circlePaintWith;
        float dmax = (progressWith - circlePaintWith) / 2.0f;
        //rect的上下左右分别代表,进度条圆环最外围的坐标
        rect.left = circleX - circleRealRadius + circlePaintWith;
        rect.right = circleX + circleRealRadius - circlePaintWith;
        rect.top = circleY - circleRealRadius + circlePaintWith;
        rect.bottom = circleY + circleRealRadius - circlePaintWith;
        float currentAngle = (float) 360 * currentProgress / (float) maxProgress;
        //绘制出当前进度条
        canvas.drawArc(rect, -90, currentAngle, false, progressPaint);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        SrceenWidth = measureWidth(widthMeasureSpec);
        SrceenHeight = measureHeight(heightMeasureSpec);
    }

    private int measureWidth(int widthMeasureSpec) {
        int result;
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        int padding = getPaddingLeft() + getPaddingRight();
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = getSuggestedMinimumHeight();
            result += padding;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.max(result, size);
            }
        }
        return result;
    }

    private int measureHeight(int heightMeasureSpec) {
        int result;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        int padding = getPaddingTop() + getPaddingBottom();
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = getSuggestedMinimumHeight();
            result += padding;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.max(result, size);
            }
        }
        return result;
    }

    /**
     * 数据转换: dp---->px
     */
    private float dp2Px(float dp) {
        return dp * getContext().getResources().getDisplayMetrics().density;
    }

    /**
     * 设置当前进度
     * @param progress
     * progress (0 - 100) 
     */
    public void setProgress(int progress) {
        if (progress > maxProgress) {
            progress = maxProgress;
        } else if (progress < 0) {
            progress = 0;
        }
        this.currentProgress = progress;
        invalidate();
    }

    /**
     * 设置背景圆环颜色
     *
     * @param color
     */
    public void setBackCircleColor(int color) {
        this.circleColor = color;
        circlePaint.setColor(color);
    }

    /**
     * 设置背景圆环宽度
     */
    public void setBackCircleWith(int width) {
        this.circlePaintWith = width;
        circlePaint.setStrokeWidth(width);
    }

    /**
     * 设置进度条圆环颜色
     *
     * @param color
     */
    public void setProgressColor(int color) {
        this.progressColor = color;
        progressPaint.setColor(color);
    }

    /**
     * 设置进度条圆环宽度
     */
    public void setProgressWith(int width) {
        this.progressWith = width;
        progressPaint.setStrokeWidth(width);
    }
}

使用的时候可以配合Hanlder来使用,实时的去更新这个view,调用它的setProgress方法(注意progress的范围是在0-100之间),类似下载,我们应该先计算好当前进度在传入这个view中就好了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值