自定义Drawable实现环形进度条.

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;

/**
 * 圆形进度条
 * Created by WSJ on 2016/12/15.
 */

public class CircleProgressDrawable extends Drawable {
    private static final String TAG = "CircleProgressDrawable";
    // 画笔.
    private Paint mPaint;
    // 当前进度.
    private int mCurProgress;
    // 总进度.
    private int mMaxProgress;
    // 开始角度.
    private int mStartAngle;
    // 旋转方向, 顺时针,逆时针.
    private int mOritation;
    // 圆环宽度.
    private int mRingWidth;
    /**
     * 进度条开始位置.
     */
    public interface StartPointType {
        // 右
        public static final int START_ANGLE_RIGHT = 0;
        // 下
        public static final int START_ANGLE_BOTTOM = 90;
        // 左
        public static final int START_ANGLE_LEFT = 180;
        // 上
        public static final int START_ANGLE_TOP = 270;
    }

    /**
     * 进度条方向
     */
    public interface ProgressOrientation {
        // 顺时针.
        public static final int PROGRESS_ORITATION_CLOCKWISE = 0x00;
        // 逆时针.
        public static final int PROGRESS_ORITAITON_ANTICLOCKWISE = 0x01;
    }
    public void setOrientation(int orientation){
        if (orientation == ProgressOrientation.PROGRESS_ORITAITON_ANTICLOCKWISE || orientation == ProgressOrientation.PROGRESS_ORITATION_CLOCKWISE){
            mOritation = orientation;
        }else {
            throw new RuntimeException("Orientation value must be from interface ProgressOrientation !");
        }
    }


    public CircleProgressDrawable(int maxProgress, int ringWidth, int ringColor,int startAngle){
        mMaxProgress = maxProgress;
        mCurProgress = 0;
        mStartAngle = startAngle;
        mRingWidth = ringWidth;
        // 默认是逆时针方向.
        mOritation = ProgressOrientation.PROGRESS_ORITAITON_ANTICLOCKWISE;

        mPaint = new Paint();
        // 描边
        mPaint.setStyle(Paint.Style.STROKE);
        // 设置颜色
        mPaint.setColor(ringColor);
        // 设置抗锯齿
        mPaint.setAntiAlias(true);
        // 设置圆环宽度
        mPaint.setStrokeWidth(mRingWidth);
        // 设置圆角
        mPaint.setStrokeCap(Paint.Cap.ROUND);
    }

    public int getCurProgress(){
        return mCurProgress;
    }
    /**
     * 设置进度百分比 .
     * @param curProgress 当前进度.
     */
    public void setCurProgress(int curProgress){
        // 赋值
        if (mOritation == ProgressOrientation.PROGRESS_ORITATION_CLOCKWISE){
            // 顺时针.
            mCurProgress = curProgress > mMaxProgress ? mMaxProgress : curProgress;
        }else {
            // 逆时针
            mCurProgress = -(curProgress > mMaxProgress ? mMaxProgress : curProgress);
        }
        // 重绘
        invalidateSelf();
    }
    @Override
    public void draw(Canvas canvas) {
        // 清除画布
        canvas.drawColor(Color.WHITE);

        // 获取尺寸
        final Rect bounds = getBounds();
        // 计算半径
        final int radius = (Math.min(bounds.width(),bounds.height()) - mRingWidth) / 2;
        // 计算矩形位置.
        final int offsetX = (bounds.width() - radius * 2)/2 ;
        final int offsetY = (bounds.height() - radius * 2)/2 ;
        RectF rect = new RectF(offsetX,offsetY,offsetX + radius * 2,offsetY + radius *2);

        // 1. 绘制圆环
        final int centerX = bounds.width() / 2;
        final int centerY = bounds.height() / 2;
        final float outRingRadius = radius + mRingWidth / 2;
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(1);
        canvas.drawCircle(centerX,centerY,outRingRadius,mPaint);

        // 计算角度.
        int angle = (int) ((mCurProgress * 1.0 / mMaxProgress) * 360);
        // 2. 绘制进度圆环.
        mPaint.setStrokeWidth(mRingWidth);
        canvas.drawArc(rect,mStartAngle,angle,false,mPaint);

        // 3. 绘制内圆
        final float innerMaxCircleRadius = radius - mRingWidth / 2 + 1;
        final float innerCurCircleRadius = (int) (innerMaxCircleRadius * (mCurProgress * 1.0 / mMaxProgress));

        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(centerX,centerY,Math.abs(innerCurCircleRadius),mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }

    @Override
    public int getIntrinsicHeight() {
        return getBounds().height();
    }

    @Override
    public int getIntrinsicWidth() {
        return getBounds().width();
    }
}

推荐阅读更多精彩内容