Android自定义View圆环带文字进度条

项目原型图中有这样的一种进度条
Android自定义View圆环带文字进度条_第1张图片
由于懒得找第三方(找到的不一定合用,有找的时间自己也就写了一个)
自定义所需要的属性


<resources>

    <attr name="innercirclediameter" format="dimension">attr>
    <attr name="outercirclediameter" format="dimension">attr>
    <attr name="innercolor" format="color">attr>
    <attr name="outercolor" format="color">attr>
    <attr name="divlength" format="dimension">attr>
    <attr name="divcolor" format="color">attr>
    <attr name="noselectedoutcolor" format="color">attr>
    <attr name="toptextsize" format="dimension">attr>
    <attr name="buttomtextsize" format="dimension">attr>
    <attr name="textcolor" format="color">attr>
    <attr name="toptext" format="string">attr>
    <attr name="buttomtext" format="string">attr>
    <attr name="progress" format="float">attr>

    <declare-styleable name="MyCircleProgress">
        <attr name="innercirclediameter">attr>
        <attr name="outercirclediameter">attr>
        <attr name="innercolor">attr>
        <attr name="outercolor">attr>
        <attr name="divlength">attr>
        <attr name="divcolor">attr>
        <attr name="noselectedoutcolor">attr>
        <attr name="toptextsize">attr>
        <attr name="buttomtextsize">attr>
        <attr name="textcolor">attr>
        <attr name="toptext">attr>
        <attr name="buttomtext">attr>
        <attr name="progress">attr>
    declare-styleable>

resources>

自定义View类

package com.sunrui.circleprogressbar;

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

public class MyCircleProgressBar extends View {

    private int innerCircleDiameter;
    private int outerCircleDiameter;
    private int innerColor;
    private int outercolor;
    private int divLength;
    private int divColor;
    private int noSelectedOutColor;
    private int topTextSize;
    private int buttomTextSize;
    private int textColor;
    private double progress;
    private String topText;
    private String buttomText;
    private Rect topF, buttomF;
    private Paint topP, buttomP, outerSP, outerP, divP, innerP;
    private int width = 0;
    private int height = 0;
    private RectF innerF, divF,outerF;

    public void setProgress(double progress) {
        this.progress = progress;
        postInvalidate();
    }

    public void setTopText(String topText) {
        this.topText = topText;
        topP.getTextBounds(topText, 0, topText.length(), topF);
        postInvalidate();
    }

    public void setButtomText(String buttomText) {
        this.buttomText = buttomText;
        buttomP.getTextBounds(buttomText, 0, buttomText.length(), buttomF);
        postInvalidate();
    }

    public MyCircleProgressBar(Context context, AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyCircleProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(
                attrs, R.styleable.MyCircleProgress, 0, 0);
        int n = typedArray.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
            case R.styleable.MyCircleProgress_innercirclediameter:
                innerCircleDiameter = typedArray.getDimensionPixelSize(i, 0);
                break;
            case R.styleable.MyCircleProgress_outercirclediameter:
                outerCircleDiameter = typedArray.getDimensionPixelSize(i, 0);
                break;
            case R.styleable.MyCircleProgress_innercolor:
                innerColor = typedArray.getColor(i, Color.RED);
                break;
            case R.styleable.MyCircleProgress_outercolor:
                outercolor = typedArray.getColor(i, Color.RED);
                break;
            case R.styleable.MyCircleProgress_divlength:
                divLength = typedArray.getDimensionPixelSize(i, 0);
                break;
            case R.styleable.MyCircleProgress_divcolor:
                divColor = typedArray.getColor(i, Color.GRAY);
                break;
            case R.styleable.MyCircleProgress_noselectedoutcolor:
                noSelectedOutColor = typedArray.getColor(i, Color.GREEN);
                break;
            case R.styleable.MyCircleProgress_toptextsize:
                topTextSize = typedArray.getDimensionPixelSize(i, 0);
                break;
            case R.styleable.MyCircleProgress_buttomtextsize:
                buttomTextSize = typedArray.getDimensionPixelSize(i, 0);
                break;
            case R.styleable.MyCircleProgress_textcolor:
                textColor = typedArray.getColor(i, Color.WHITE);
                break;
            case R.styleable.MyCircleProgress_toptext:
                topText = typedArray.getString(i);
                break;
            case R.styleable.MyCircleProgress_buttomtext:
                buttomText = typedArray.getString(i);
                break;
            case R.styleable.MyCircleProgress_progress:
                progress = typedArray.getFloat(i, (float) 100.0);
                break;
            default:
                break;
            }
        }
        topF = new Rect();
        topP = new Paint();
        topP.setTextSize(topTextSize);
        topP.setColor(textColor);
        topP.getTextBounds(topText, 0, topText.length(), topF);
        buttomF = new Rect();
        buttomP = new Paint();
        buttomP.setTextSize(buttomTextSize);
        buttomP.setColor(textColor);
        buttomP.getTextBounds(buttomText, 0, buttomText.length(), buttomF);
        outerSP = new Paint();
        outerSP.setColor(outercolor);
        outerP = new Paint();
        outerP.setColor(noSelectedOutColor);
        divP = new Paint();
        divP.setColor(divColor);
        innerP = new Paint();
        innerP.setColor(innerColor);
        typedArray.recycle();
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        width = 0;
        height = 0;

        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        switch (specMode) {
        case MeasureSpec.EXACTLY:
            width = getPaddingLeft() + getPaddingRight() + specSize;
            break;
        case MeasureSpec.AT_MOST:
            width = getPaddingLeft() + getPaddingRight() + outerCircleDiameter;
        default:
            break;
        }

        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);

        switch (specMode) {
        case MeasureSpec.EXACTLY:
            height = getPaddingTop() + getPaddingBottom() + specSize;
            break;
        case MeasureSpec.AT_MOST:
            height = getPaddingTop() + getPaddingBottom() + outerCircleDiameter;
            break;
        default:
            break;
        }
        innerF = new RectF((width - innerCircleDiameter) / 2,
                (height - innerCircleDiameter) / 2,
                (width - innerCircleDiameter) / 2 + innerCircleDiameter,
                (height - innerCircleDiameter) / 2 + innerCircleDiameter);
        divF = new RectF((width - innerCircleDiameter) / 2 - divLength,
                (height - innerCircleDiameter) / 2 - divLength,
                (width - innerCircleDiameter) / 2 + innerCircleDiameter
                        + divLength, (height - innerCircleDiameter) / 2
                        + innerCircleDiameter + divLength);
        outerF = new RectF((width - outerCircleDiameter) / 2,
                (height - outerCircleDiameter) / 2,
                (width - outerCircleDiameter) / 2 + outerCircleDiameter,
                (height - outerCircleDiameter) / 2 + outerCircleDiameter);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawArc(outerF, -90, 360, false, outerP);
        canvas.drawArc(outerF, -90, (float)(progress/100)*360, true, outerSP);
        canvas.drawArc(divF, 0, 360, false, divP);
        canvas.drawArc(innerF, 0, 360, false, innerP);
        canvas.drawText(topText, (width - topF.width()) / 2,
                height / 2 - topF.height() / 4, topP);
        canvas.drawText(buttomText, (width - buttomF.width()) / 2, height / 2
                + buttomF.height(), buttomP);
    }
}

layout布局

"http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.sunrui.circleprogressbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    "@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        custom:innercirclediameter="160px"
        custom:outercirclediameter="180px"
        custom:innercolor="#ff0000"
        custom:outercolor="#ff0000"
        custom:divlength="2px"
        custom:divcolor="#dedede"
        custom:noselectedoutcolor="#d3d3d3"
        custom:toptextsize="13sp"
        custom:buttomtextsize="16sp"
        custom:textcolor="#ffffff"
        custom:toptext="进度 85%"
        custom:progress="85"
        custom:buttomtext="我要投资"/>


使用方式

 circleProgressBar = (MyCircleProgressBar) findViewById(R.id.progress);
        circleProgressBar.setTopText("完成 50%");
        circleProgressBar.setProgress(50);
        circleProgressBar.setButtomText("米多利");

效果
Android自定义View圆环带文字进度条_第2张图片

交流进步 QQ:100917083

你可能感兴趣的:(Android)