自定义View 进度条

1.在values下面新建一个attrs.xml,现在里面定义我们的自定义属性,

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundProgressBar">
        <attr name="roundColor" format="color"></attr>
        <attr name="roundProgressColor" format="color"></attr>
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="textColor" format="color"></attr>
        <attr name="textSize" format="dimension"></attr>
        <attr name="max" format="integer"></attr>
        <attr name="textIsDisplayable" format="boolean"></attr>
        <attr name="style">
            <enum name="STROKE" value="0"></enum>
            <enum name="FILL" value="1"></enum>
        </attr>
    </declare-styleable>
    
</resources>

2、创建一个customView 自定义view类  

package com.example.customprogress;

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.view.View;

public class RoundProgressBar extends View
{
    private Paint mPaint; //画笔
    private int roundColor; //圆环的颜色
    private int roundProgressColor; //圆环进度的颜色
    private int textColor; //百分比字符串的颜色
    private float textSize; //百分比字体的大小
    private float roundWidth;//圆环的宽度
    private int max;//最大进度
    private int progerss;//当前进度
    private boolean textIsDisplayable; //是否显示
    private int style;//进度风格 
    public static final int STROKE = 0;
    public static final int FILL = 1;


    //第一步重写所以构造方法
    public RoundProgressBar(Context context)
    {
        super(context,null);
        // TODO Auto-generated constructor stub
    }

    public RoundProgressBar(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        //创建画笔对象
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // 第二步   初始化自定义属性
        initAttrs(context,attrs);
        
    }

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


    }

    //第三步  重写onDraw方法
    @Override
    protected void onDraw(Canvas canvas)
    {        
        super.onDraw(canvas);

        //画圆环
        int center = getWidth()/2; //获取圆形的x坐标
        int radius =(int)(center-roundWidth/2); //圆环的半径
        mPaint.setColor(roundColor);//设置圆环的颜色
        mPaint.setStyle(Paint.Style.STROKE);//空心
        mPaint.setStrokeWidth(roundWidth);//宽度
        //画出圆环
        canvas.drawCircle(center, center, radius, mPaint);


        //画进度百分比
        mPaint.setStrokeWidth(0);
        mPaint.setColor(textColor);
        mPaint.setTextSize(textSize);
        mPaint.setTypeface(Typeface.DEFAULT_BOLD);//设置字体        
        //计算中间的进度百分比,先转换成float在进行除法运算,不然都为0  
        int percent = (int)(((float)progerss/ (float)max) * 100);
        float textWidth = mPaint.measureText(percent+"%");//获取字体宽度
        if(textIsDisplayable&&percent!=0&&style==STROKE)
        {
            //画出中间进度值
            canvas.drawText(percent+"%",center-textWidth/2, center+textSize/2, mPaint);
        }


        //画圆弧
        mPaint.setStrokeWidth(roundWidth);
        mPaint.setColor(roundProgressColor);//圆弧进度颜色

        RectF oval = new RectF(center-radius, center-radius,center+radius, center+radius);

        switch (style)
        {
        case STROKE:
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(oval,0,360*progerss/max, false,mPaint);//根据进度画圆弧
            break;
        case FILL:
            //填充的圆
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            if(progerss!=0)
            {
                canvas.drawArc(oval, 0, 360*progerss/max,true, mPaint);
            }
            break;
        }


    }


    public synchronized int getMax()
    {
        return max;
    }

    public synchronized void setMax(int max)
    {
        if(max<0)
        {
            throw new IllegalArgumentException("max not less than 0");
        }
        this.max = max;
    }

    public synchronized int getProgress()
    {
        return progerss;
    }

    public synchronized void setProgress(int progress)
    {
        if(progress<0){
            throw new IllegalArgumentException("progress not less than 0");
        }
        if(progress>max){
            this.progerss = max;
        }
        if(progress<max){

            this.progerss = progress;
            
        }
        postInvalidate();//刷新界面调用postInvalidate()能在非UI线程中刷新
    }

    public int getCricleColor() {  
        return roundColor;  
    }  

    public void setCricleColor(int cricleColor) {  
        this.roundColor = cricleColor;  
    }  

    public int getCricleProgressColor() {  
        return roundProgressColor;  
    }  

    public void setCricleProgressColor(int cricleProgressColor) {  
        this.roundProgressColor = cricleProgressColor;  
    }  

    public int getTextColor() {  
        return textColor;  
    }  

    public void setTextColor(int textColor) {  
        this.textColor = textColor;  
    }  

    public float getTextSize() {  
        return textSize;  
    }  

    public void setTextSize(float textSize) {  
        this.textSize = textSize;  
    }  

    public float getRoundWidth() {  
        return roundWidth;  
    }  

    public void setRoundWidth(float roundWidth) {  
        this.roundWidth = roundWidth;  
    }  


    //初始化自定义属性
    private void initAttrs(Context context,AttributeSet attrs)
    {
        //获取TypedArray 对象   得到自定义属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar);

        //初始化属性
        roundColor = typedArray.getColor(R.styleable.RoundProgressBar_roundColor,Color.RED );
        roundProgressColor = typedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor,Color.GREEN);
        textColor = typedArray.getColor(R.styleable.RoundProgressBar_textColor,Color.GREEN);
        textSize = typedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
        roundWidth = typedArray.getDimension(R.styleable.RoundProgressBar_roundWidth,5);
        max = typedArray.getInteger(R.styleable.RoundProgressBar_max,100);
        textIsDisplayable = typedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable,true);
        style = typedArray.getInt(R.styleable.RoundProgressBar_style,0);

        //一定要注意  用完TypedArray 对象 要回收
        typedArray.recycle();
    }




}

3、在布局文件中使用自定义View

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android_custom="http://schemas.android.com/apk/res/com.example.customprogress"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".MainActivity" >  
    <com.example.customprogress.RoundProgressBar 
        
        android:id="@+id/custom_progress"
        android:layout_width="80dp"
        android:layout_height="80dp"   
        android_custom:roundColor="#4f5f6f"
        android_custom:textColor="#9a32cd"
        android_custom:roundProgressColor="#f00"
        android_custom:textIsDisplayable="true"
        android_custom:roundWidth="10dp"
        android_custom:textSize="18sp"
        android_custom:style="STROKE"      
        />
   
   
</LinearLayout>
原文地址:https://www.cnblogs.com/pbq-dream/p/5399961.html