自定义圆环ProgressBar,带弹簧动画

先给大家上效果图

这里写图片描述
这里写图片描述

看上去还不错对吧

其实实现起来也很简单的,整理一下要用到的知识点:
自定义View 画椭圆drawOval 画圆弧drawArc 画圆drawCircle 画文字drawText

给大家上代码、然后是一些需要注意的点

  • 重写自定义View的三个构造方法
    public FlexProgressView(Context context) {
        this(context, null);
    }

    public FlexProgressView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlexProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    一般应该都是这么写的,就是不管使用哪几种创建view的方式,最后都会调到init()方法中去
  • 然后是init()方法,去初始化一下画笔,进度条宽度,颜色什么的,当然也不会写死这些东西,后面都暴露方法出去,可以让
   private void init() {
        max = 100;
        mStrokeWidth = 10;
        mProgressWidth = 30;
        mTextSize = 30 ;
        // 边框
        mStrokePaint = new Paint();
        mStrokePaint.setColor(Color.RED);
        mStrokePaint.setStyle(Paint.Style.STROKE);
        mStrokePaint.setAntiAlias(true);
        mStrokePaint.setStrokeWidth(mStrokeWidth);
        // 进度条
        mProPaint = new Paint();
        mProPaint.setColor(Color.BLUE);
        mProPaint.setStyle(Paint.Style.STROKE);
        mProPaint.setAntiAlias(true);
        mProPaint.setStrokeWidth(mProgressWidth);
        // 两边的小球
        cPaint = new Paint();
        cPaint.setColor(Color.BLUE);
        cPaint.setStyle(Paint.Style.FILL);
        cPaint.setAntiAlias(true);
        // 写文字
        mTextPaint = new Paint();
        mTextPaint.setColor(Color.BLUE);
        mTextPaint.setStyle(Paint.Style.STROKE);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(mTextSize);
        // 给一个默认的进度值
        setProgress(30);
    }
  • 然后重写父类的onMeasure方法,让这个控件变成正方形的
  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
//        mHeight = MeasureSpec.getSize(heightMeasureSpec);
        mHeight = mWidth;
        setMeasuredDimension(mWidth, mWidth);
    }
  • 然后重写父类的onDraw方法,在画布上画我们需要背景线、进度条、文字、还有进度条两端的小球
  @Override
    protected void onDraw(Canvas canvas) {
        // 如果进度条细一些的话、就应该显示在边框的中间,反之边框应该显示在进度条的中间
        float stWidth = mProgressWidth > mStrokeWidth ? mProgressWidth : mStrokeWidth;

        RectF oval = new RectF();                     //RectF对象
        oval.left = stWidth / 2;                      //左边
        oval.top = stWidth / 2;                       //上边
        oval.right = mWidth - (stWidth / 2);          //右边
        oval.bottom = mHeight - (stWidth / 2);        //下边
        // 画边框
        canvas.drawOval(oval, mStrokePaint);
        // 画进度
        canvas.drawArc(oval, startAngle, sweepAngle, false, mProPaint);

        // 画左边的小球
        float radius = (mWidth / 2) - (stWidth / 2);
        float centerX = mWidth / 2;
        float centerY = mHeight / 2;
        double aa = startAngle * Math.PI / 180;
        float x1 = (float) (centerX + (radius) * Math.cos(aa));
        float y1 = (float) (centerY + (radius) * Math.sin(aa));
        canvas.drawCircle(x1, y1, mProgressWidth / 2, cPaint);

        // 画右边的小球
        float f = (270 - startAngle + 270);
        if (f >= 360)   f = f - 360;
        aa = f * Math.PI / 180;
        x1 = (float) (centerX + (radius) * Math.cos(aa));
        y1 = (float) (centerY + (radius) * Math.sin(aa));
        canvas.drawCircle(x1, y1, mProgressWidth / 2, cPaint);

        // 画文字
        if (mVisibility == View.VISIBLE){ // 对外暴露控制方法,是否显示
            Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
            int baseline = (int) ((oval.bottom + oval.top - fontMetrics.bottom - fontMetrics.top) / 2);
            mTextPaint.setTextAlign(Paint.Align.CENTER);
            int pro = (int) progress;
            canvas.drawText(pro+"", oval.centerX(), baseline, mTextPaint);
        }
    }

这里需要注意的几个地方就是drawArc还有画进度条的端的小球,如果不画两端的小球进度条会比较难看,感兴趣的可以注释代码去试试就知道了。觉得很难理解的可以去看看 。画圆弧写文字

  • 然后是对外暴露的控制方法了,可以去设置一些画笔的大小啊,颜色啊之类的
 /**
     * 设置进度
     * @param progressWidth
     */
   public void setProgress(float progress) {
        if (progress < 0) {
            progress = 0;
        } else if (progress > max) {
            progress = max;
        }
        this.progress = progress;

        startAngle = 270 - (float) (this.progress / max * 180.0);
        sweepAngle = (270 - startAngle) * 2;

        postInvalidate();
    }

    /**
     * 设置边框颜色
     * @param color
     */
    public void setStrokeColor(int color) {
        mStrokePaint.setColor(color);
        invalidate();

    }

    /**
     * 设置进度条颜色
     * @param color
     */
    public void setProgressColor(int color) {
        mProPaint.setColor(color);
        invalidate();
    }

    /**
     * 设置边框宽度
     * @param width
     */
    public void setStrokeWidth(float width) {
        mStrokeWidth = width;
        mStrokePaint.setStrokeWidth(width);
        invalidate();
    }


    /**
     * 设置进度条的宽度
     * @param progressWidth
     */
    public void setProgressWidth(float progressWidth) {
        mProgressWidth = progressWidth;
        mProPaint.setStrokeWidth(mProgressWidth);
        invalidate();
    }

    /**
     * 设置 文字大小
     * @param textSize
     */
    public void setTextSize(int textSize) {
        mTextSize = textSize;
        mTextPaint.setTextSize(mTextSize);
        invalidate();
    }

    /**
     * 设置 文字颜色
     */
    public void setTextColor(int textColor) {
        mTextPaint.setColor(textColor);
        invalidate();
    }

    /**
     * 设置文字是否可见
     * @param visibility View.VISIBLE 可见
     */

    public void setTextVisibility(int visibility){
        if (mVisibility != visibility){
            mVisibility = visibility;
            invalidate();
        }
    }

最后给大家看一下运行时的样子

这里写图片描述

给大家放上资源地址吧

转载请注明出处 http://blog.csdn.net/q771410116/article/details/77919760
源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值