自定义多进度环形进度条

效果图
自定义多进度环形进度条_第1张图片

使用方法

       MRoundProgressBar mPB  = Fid(R.id.mPb);
        mPB.addProgress(10,Color.YELLOW);
        mPB.addProgress(30,Color.BLUE);
        mPB.addProgress(10,Color.GREEN);
        mPB.addProgress(10, Color.GRAY);
//        mPB.setProgressBackgroud(Color.BLACK);

相关说明

1.可能实际需求不需要中间的扇形和文字 可以直接去掉 在相关中
2.一般的progress会考虑到线程安全,那个是单进度。(下文源码中注释中有类似处理的代码)
本文暂时没有贴出具体处理相关问题。只是核心如何画

    <com.rex.simpleproject.view.MRoundProgressBar
        android:id="@+id/mPb"
        android:layout_margin="5dp"
        android:layout_width="160dp"
        android:layout_height="160dp"
        android:layout_gravity="center_horizontal"
        app:textIsDisplayable="true"
        app:roundBg="@color/main"
        app:max="100"
        >
    com.rex.simpleproject.view.MRoundProgressBar>

源码

package com.rex.simpleproject.view;

/**
 * Created by rex on 2016/6/6 0006.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.rex.simpleproject.R;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 可以添加多个进度的进度条
 */
public class MRoundProgressBar extends View {

    private Paint paint;
    private int progress;
    private int lastStart;//进度起点位置
    private int centre;
    private int radius;
    private int roundWidth;
    private int roundBg;
    private int max;
    private List progressInfos = new ArrayList<>();
    private TypedArray mTypedArray;
    private boolean textIsDisplayable;

    public MRoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
       mTypedArray = context.obtainStyledAttributes(attrs,
                R.styleable.MRoundProgressBar);
    }

    public MRoundProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        mTypedArray = context.obtainStyledAttributes(attrs,
                R.styleable.MRoundProgressBar);
    }

    public MRoundProgressBar(Context context) {
        super(context);
    }

    private void init() {
        if (mTypedArray ==null){
            roundBg =  Color.RED;
            roundWidth = 10;
            max =  100;
            lastStart = -90;
            textIsDisplayable = false;
        }else {
            roundBg = mTypedArray.getColor(R.styleable.MRoundProgressBar_roundBg, Color.RED);
            roundWidth = mTypedArray.getInt(R.styleable.MRoundProgressBar_roundWidth, 10);
            max = mTypedArray.getInt(R.styleable.MRoundProgressBar_max, 100);
            lastStart = mTypedArray.getInt(R.styleable.MRoundProgressBar_lastStart, -90);
            textIsDisplayable = mTypedArray.getBoolean(R.styleable.MRoundProgressBar_textIsDisplayable,false);
        }

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        init();
        paint = new Paint();
        Log.i("rex",
                "          roundBg="+roundBg+
                "          roundWidth="+roundWidth+
                "          max="+max+
                "          lastStart="+lastStart
        );
        /**
         * 画最外层大圆
         */
        centre = getWidth() / 2;
        radius = (int) (centre - roundWidth / 2);
        paint.setColor(roundBg); //设置圆环的颜色
        paint.setStyle(Paint.Style.STROKE); //设置空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setAntiAlias(true);  //消除锯齿
        canvas.drawCircle(centre, centre, radius, paint); //画出圆环

        Iterator it = progressInfos.iterator();
        while (it.hasNext()) {
            ProgressInfo info = it.next();
            paintArc(info.progress, info.color, canvas);
            Log.i("rex", "come in onDraw");
        }

            /**
             * 画总进度扇形
             */
        paint.setStrokeWidth(0); //设置圆环的宽度
        paint.setColor(Color.parseColor("#FFC0CB"));  //设置进度的颜色

        radius = radius - roundWidth/2;
        RectF oval2 = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius);  //用于定义的圆弧的形状和大小的界限


        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawArc(oval2, -90, lastStart+90, true, paint);  //根据进度画扇形


        /**
         * 画进度百分比
         */

        if (textIsDisplayable) {
            String alProgress ="已使用"+(lastStart+90)*100/ 360.00f+"%";
            paint.setStrokeWidth(0);
            paint.setColor(roundBg);
            paint.setTextSize(18);
            paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
            float textWidth = paint.measureText(alProgress);   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
            canvas.drawText(alProgress, centre - textWidth / 2, centre + 18 / 2, paint);
        }

    }

    /**
     * 添加单个进度
     * @param progress
     * @param color
     */
    public void addProgress(int progress, final int color) {
        progressInfos.add(new ProgressInfo(progress, color));
        invalidate();
    }

    /**
     * 直接添加所有进度
     * @param infos
     */
    public void addProgressList(List infos) {
        progressInfos.clear();
        progressInfos.addAll(infos);
        invalidate();
    }

    public void setProgressBackgroud(int color){
        roundBg = color;
        invalidate();
    }

    public void reSet() {
        progressInfos.clear();
        invalidate();
    }

    /**
     * @param color
     * @param progress 进度确定弧度范围
     */
    private void paintArc(int progress, int color, Canvas canvas) {
        Log.i("rex", "come in paintArc");
        int range = 360 * progress / max;
        // 画圆弧 ,画圆环的进度
        //设置进度是实心还是空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setColor(color);  //设置进度的颜色
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius);  //用于定义的圆弧的形状和大小的界限
        paint.setStyle(Paint.Style.STROKE);
//        //起点--距离
        Log.i("rex", "lastStart=" + lastStart);
        canvas.drawArc(oval, lastStart, range, false, paint);  //根据进度画圆弧
        lastStart = lastStart + range;


    }


    class ProgressInfo {
        private int color;
        private int progress;

        @Override
        public String toString() {
            return "ProgressInfo{" +
                    "color=" + color +
                    ", progress=" + progress +
                    '}';
        }

        public ProgressInfo(int progress, int color) {
            this.color = color;
            this.progress = progress;
        }
    }



//    public synchronized int getMax() {
//        return max;
//    }
//
//    /**
//     * 设置进度的最大值
//     * @param max
//     */
//    public synchronized void setMax(int max) {
//        if(max < 0){
//            throw new IllegalArgumentException("max not less than 0");
//        }
//        this.max = max;
//    }
//
//    /**
//     * 获取进度.需要同步
//     * @return
//     */
//    public synchronized int getProgress() {
//        return progress;
//    }
//
//    /**
//     * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
//     * 刷新界面调用postInvalidate()能在非UI线程刷新
//     * @param progress
//     */
//    public synchronized void setProgress(int progress) {
//        if(progress < 0){
//            throw new IllegalArgumentException("progress not less than 0");
//        }
//        if(progress*100/360> 360-lastStart+90){
//            progress = max;
//        }
//        if(progress <= max){
//            this.progress = progress;
//            postInvalidate();
//        }
//
//    }

}

用于自定义xml属性


<resources>
    <declare-styleable name="MRoundProgressBar">
        <attr name="roundBg" format="color"/>
        <attr name="roundWidth" format="dimension">attr>
        <attr name="max" format="integer">attr>
        <attr name="textIsDisplayable" format="boolean">attr>
        <attr name="lastStart" format="integer">attr>
    declare-styleable>
resources>

你可能感兴趣的:(学习心得,自定义多进度进度条,自定义progres,Android,xml自定义属性获取)