1. 程式人生 > >移動開發---CircleProgress帶數字進度條

移動開發---CircleProgress帶數字進度條

package com.message.skeul.mm.marks.main;

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.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.message.skeul.mm.marks.R;


public class CircleProgress extends View {
    private Paint bgPaint;
    private Paint fgPaint;
    private TextPaint textPaint;
    private int bgColor;
    private int fgColor;
    private int textColor;
    private int textSize;
    private int strokeWidth;
    private int radius;
    private int centerX;
    private int centerY;
    private int progress;
    private RectF rectF;
    private String percent="";

    public CircleProgress(Context context) {
        this(context,null);
    }

    public CircleProgress(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar,defStyleAttr,0);
        bgColor=typedArray.getColor(R.styleable.CircleProgressBar_bg_color, Color.parseColor("#EBEBEB"));
        fgColor=typedArray.getColor(R.styleable.CircleProgressBar_fg_color, Color.parseColor("#18B1E5"));
        textColor=typedArray.getColor(R.styleable.CircleProgressBar_progress_text_color, Color.parseColor("#18B1E5"));
        textSize= (int) typedArray.getDimension(R.styleable.CircleProgressBar_progress_text_size, convert2px(context,TypedValue.COMPLEX_UNIT_SP,5));
        strokeWidth = (int) typedArray.getDimension(R.styleable.CircleProgressBar_progress_width, convert2px(context,TypedValue.COMPLEX_UNIT_DIP,3));
        radius= (int) typedArray.getDimension(R.styleable.CircleProgressBar_radius, convert2px(context,TypedValue.COMPLEX_UNIT_DIP,15));
        progress= typedArray.getInt(R.styleable.CircleProgressBar_progress, 60);
        this.percent=progress+"%";

        typedArray.recycle();

        initPaint(context);
    }

    private void initPaint(Context context){
        bgPaint=new Paint();
        bgPaint.setAntiAlias(true);
        bgPaint.setStyle(Paint.Style.STROKE);
        bgPaint.setStrokeWidth(strokeWidth);
        bgPaint.setColor(bgColor);

        fgPaint=new Paint();
        fgPaint.setAntiAlias(true);
        fgPaint.setStyle(Paint.Style.STROKE);
        fgPaint.setStrokeCap(Paint.Cap.ROUND);
        fgPaint.setStrokeWidth(strokeWidth);
        fgPaint.setColor(fgColor);

        textPaint=new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(textColor);
        textPaint.setTextSize(convert2px(context,TypedValue.COMPLEX_UNIT_SP,textSize));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawCircle(canvas);
        drawArc(canvas);
        drawProgress(canvas);
    }

    private void drawCircle(Canvas canvas){
        canvas.drawCircle(centerX,centerY,radius,bgPaint);
    }

    private void drawArc(Canvas canvas){
        canvas.drawArc(rectF,-90,progress*360/100,false,fgPaint);
    }

    private void drawProgress(Canvas canvas){
        int progressWidth= (int) textPaint.measureText(percent);
        int progressHeight= (int) textPaint.ascent()+(int)textPaint.descent();
        canvas.drawText(percent,centerX-progressWidth/2,centerY-progressHeight/2,textPaint);
    }

    public void setProgress(int progress){
        this.progress=progress;
        this.percent=progress+"%";
        invalidate();
    }

    public void setFgColor(int fgColor){
        fgPaint.setColor(fgColor);
        textPaint.setColor(fgColor);
//        this.fgColor=fgColor;
//        this.textColor=fgColor;
//        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width=calcuSize(widthMeasureSpec);
        int height=calcuSize(heightMeasureSpec);
        int measuredSize=Math.min(width,height);
        centerX=centerY=measuredSize/2;
        rectF=new RectF(centerX-radius,centerY-radius,centerX+radius,centerY+radius);
        setMeasuredDimension(measuredSize,measuredSize);
    }

    private int calcuSize(int measureSpec){
        int result=0;
        int specMode=MeasureSpec.getMode(measureSpec);
        int specSize=MeasureSpec.getSize(measureSpec);

        if (specMode==MeasureSpec.EXACTLY){
            result=specSize;
        }else {
            result=2*(radius+strokeWidth);
        }

        return result;
    }

    public int convert2px(Context context, int type, int original) {
        return (int) TypedValue.applyDimension(type,original, context.getResources().getDisplayMetrics());
    }
}

在attrs.xml中

<declare-styleable name="CircleProgressBar">
        <attr name="bg_color" format="color"/>
        <attr name="fg_color" format="color"/>
        <attr name="progress_text_color" format="color"/>
        <attr name="progress_text_size" format="dimension"/>
        <attr name="progress_width" format="dimension"/>
        <attr name="radius" format="dimension"/>
        <attr name="progress" format="integer"/>
    </declare-styleable>

引用
 

                <com.message.skeul.mm.marks.main.CircleProgress 
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    android:id="@+id/progressbar"
                    android:layout_width="55dp"
                    android:layout_height="55dp"
                    android:layout_centerVertical="true"
                    app:radius="25dp" />
progressbar.setProgress(60);