自定义环形进度条

         在学习之前如果对view常用的绘制方法不熟悉可以参考http://blog.csdn.net/harvic880925/article/details/38926877 这篇博客。那么闲言少叙我们先看一下效果


       环形进度条分四部分,第一部分绿色背景,第二部分青色圆环,第三部分白色进度外环,第四部分进度百分比。

   

       

package com.qc.wintrax.utils;

import com.example.multiwindow.R;

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;

/**
 * Created by forrey on 2016/12/11.
 */
public class CirclePercentView extends View {
 
	/**
     * 画笔对象的引用
     */
    private Paint paint;

    /**
     * 圆环的颜色
     */
    private int roundColor;

    /**
     * 圆环进度的颜色
     */
    private int roundProgressColor;

    /**
     * 中间进度百分比的字符串的颜色
     */
    private int textColor;

    /**
     * 中间进度百分比的字符串的字体
     */
    private float textSize;

    /**
     * 内层圆环的宽度
     */
    private float roundWidth;

    /**
     * 最大进度
     */
    private int max;

    /**
     * 当前进度
     */
    private int progress;
    /**
     * 是否显示中间的进度
     */
    private boolean textIsDisplayable;

    /**
     * 进度的风格,实心或者空心
     */
    private int style;

    public static final int STROKE = 0;
    public static final int FILL = 1;

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

    public CirclePercentView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CirclePercentView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        paint = new Paint();


        TypedArray mTypedArray = context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar);

        //获取自定义属性和默认值这里的自已定义属性都被附上定值,可以根据自己需求赋值
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColorss, Color.GREEN);
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSizess, 15);
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);
        max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
        style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);
        mTypedArray.recycle();
    }


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

        /**
         * 画内层的小圆环
         */
        int centre = getWidth()/2; //获取圆心的x坐标
        int radius = (int) (centre-roundWidth-20); //圆环的半径这里减去的20是是内层圆环距离最外侧的距离
        paint.setColor(roundColor); //设置圆环的颜色
        paint.setStyle(Paint.Style.STROKE); //设置空心
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度
        paint.setAntiAlias(true);  //消除锯齿
        canvas.drawCircle(centre, centre, radius, paint); //画出圆环
        Log.e("log", centre + "");

        /**
         * 画进度百分比
         */
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
        int percent = (int)(((float)progress / (float)max) * 100);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0
        float textWidth = paint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间

        if(textIsDisplayable  && style == STROKE){
            canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize/2, paint); //画出进度百分比
        }


        /**
         * 画圆弧 ,画圆环的进度
         */

        //设置进度是实心还是空心
        paint.setStrokeWidth(roundWidth+20); //设置大圆环的宽度
        paint.setColor(roundProgressColor);  //设置进度的颜色
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius);  //进度大圆环的椭圆所对应的矩形(实际为小圆环的外切矩形)


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

    }


    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(this.progress>progress) return;

        if(progress < 0){
            //throw new IllegalArgumentException("progress not less than 0");
        	return;
        }
        if(progress > max){
            progress = max;
        }

        if(progress <= max){
            this.progress = progress;
            postInvalidate();
        }

    }


    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;
    }



}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    xmlns:android_custom="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res/com.example.multiwindow">
    
   <com.qc.wintrax.utils.CirclePercentView
        android:id="@+id/circle_view"
        android:layout_width="120dip"
        android:layout_height="120dip"  
        android_custom:roundColor="#E1ff99"
        android:layout_centerInParent="true"
        android_custom:roundProgressColor="#fffbff"
        android_custom:textColorss="#000000"
        android:background="@drawable/circle_bg"
        android_custom:roundWidth="10dip"
        android_custom:textSizess="18sp" />
   
   <Button 
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="进度增加"
       android:layout_alignParentBottom="true"
       android:id="@+id/btn_add_progress"/>
    <Button 
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="进度递增"
       android:layout_alignParentBottom="true"
       android:layout_alignParentRight="true"
       android:id="@+id/btn_from_zero_max"/>
     <Button 
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="恢复初始"
       android:layout_alignParentBottom="true"
       android:layout_centerHorizontal="true"
       android:id="@+id/btn_from_cancle"/>
</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
    <shape  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:shape="oval"  
    android:useLevel="false">  
   
    <solid android:color="#B0DC3D"/>
     

</shape>

 代码中设置:

 

package com.example.multiwindow;

import java.util.Timer;
import java.util.TimerTask;

import com.qc.wintrax.utils.CirclePercentView;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    Button btnAdd,btnZeroToMax,btnCancel;
    CirclePercentView mCircleView;
    int count=5;
    private Timer mTimer;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mTimer = new Timer();
		mCircleView=(CirclePercentView)findViewById(R.id.circle_view);
		mCircleView.setProgress(5);
		btnAdd=(Button)findViewById(R.id.btn_add_progress);
		btnZeroToMax=(Button)findViewById(R.id.btn_from_zero_max);
		btnCancel=(Button)findViewById(R.id.btn_from_cancle);
		btnAdd.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mCircleView.setProgress(count+10);
				count+=10;
			}
		});
		btnZeroToMax.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				count=0;
				mCircleView.setProgress(count);
				try{
					mTimer.schedule(new TimerTask() {
						@Override
		                public void run() {
		                     count+=5;
		                     mCircleView.setProgress(count);      
		                }
		            }, 1000, 2000);
				}catch(Exception e){
					Toast.makeText(MainActivity.this, e.toString(), 5000).show();
				}
				
				
			}
		});
		btnCancel.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				count=0;
				mCircleView.setProgress(count);
				mTimer.purge();
			}
		});
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值