android自定义圆形进度条

2,378 阅读3分钟
原文链接: blog.csdn.net

在很多情况下,圆形进度条让我们看起来比较美观、简洁,但Android的控件并没有提供这样的View,所以这需要我们自定义,以下就是我自己实现的View,请大神们多多指教哈。现在我们先来看几张效果图,懒得去做动态图了,见谅啊:

              

用户可以自定义文字、图标,背景颜色,字体颜色等,废话不多说,现在我们来了解下是怎么实现的。

        其实也很简单,主要分为三个部分,第一部分绘制圆形实心背景,第二部绘制外部圆形进度条,第三部绘制中间文字或者图标。首先我们自定一个RoundProgressView继承View,然后在onDraw实现绘制:

float paddingLeft = getPaddingLeft();
        float paddingRight = getPaddingRight();
        float paddingTop = getPaddingTop();
        float paddingBottom = getPaddingBottom();


        //draw the background
        float left = paddingLeft + mBorderWidth;
        float top = paddingTop + mBorderWidth;
        float right = getWidth() - paddingRight - mBorderWidth;
        float bottom = getHeight() - paddingBottom - mBorderWidth;
        RectF oval = new RectF(left, top, right, bottom);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setColor(mBackgroundColor);
        mPaint.setStrokeWidth(0);
        canvas.drawArc(oval, 0, 360, true, mPaint);

绘制圆形实心背景,其中,oval是该圆形所在的矩形, mPaint需要设置style,值为FILL_AND_STROKE,表示填充内部和画边,Canvas为我们提供了方法drawArc绘制圆弧,这里我们是绘制0-360度,全部绘制成背景。

    //draw the progress
            left = paddingLeft + mBorderWidth / 2;
            top = paddingTop + mBorderWidth / 2;
            right = getWidth() - paddingRight - mBorderWidth / 2;
            bottom = getHeight() - paddingBottom - mBorderWidth / 2;
            oval = new RectF(left, top, right, bottom);

            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(mBorderWidth);
            mPaint.setColor(mBorderColor);

            canvas.drawArc(oval, -90, mCurrentAngle, false, mPaint);

接下来绘制外层的进度圆弧,不同的地方mPaint的style设置成STROKE,画边。还有需要说明的是我们是-90度开始的,表明从最顶部开始绘制。

背景和圆弧进度绘制完后,我们就可以在正中间绘制文本或者图片(bitmap),实现如下:

    //draw text
    mPaint.setColor(mTextColor);
            mPaint.setTextSize(mTextSize);
            mPaint.setStrokeWidth(0);
            mPaint.setTextAlign(Paint.Align.CENTER);
            //get font info by paint
            Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
            // calculate font height
            float fontHeight = fontMetrics.bottom - fontMetrics.top;
            // calculate font baseline
            float textBaseY = getHeight() / 2 + fontHeight / 2 -fontMetrics.bottom;
            canvas.drawText(value, getWidth() / 2, textBaseY, mPaint);

   //draw bitmap
            if (null == mMatrix) {
                mMatrix = new Matrix();
                //scale
                mMatrix.postScale(mBitmapScale, mBitmapScale);
                float dx = (getWidth() * (1 - mBitmapScale)) / 2.0f;
                float dy = (getHeight() * (1 - mBitmapScale)) / 2.0f;
                mMatrix.postTranslate(dx, dy);
            }
            canvas.drawBitmap(mBitmap, mMatrix, mPaint);

绘制文本的难点在于居中绘制,有的人还不知道textBaseY是怎么算的,这里给大家介绍一篇博文:Android Canvas drawText实现中文垂直居中

绘制图片的难点在于计算大小,我这里是根据View的比例来的,也就是mBitmapScale这个参数,默认我取2/5,用户可以自定义。

使用方法(库)我放在github上:github.com/linqssonny/…