Android 自定义绘制圆形进度条(扩展性强!)

    这几天在做电池管家的一个项目,有许多的地方需要用到这个圆形进度条,而且还要根据不同的状态去切换样式,比如手机是否在充电。充电的情况下圆形进度条中间就要显示一个充电的图标,不充电的情况下就显示电量的百分比等内容。因此花了点时间写了一个比较不错的demo,这个demo的扩展性比较强,而且也比较灵活。废话就不多说了!我先上几张图给大家看看,然后再贴上源码,好东西就是要分享,欢迎大家学习使用。

Android 自定义绘制圆形进度条(扩展性强!)_第1张图片

Android 自定义绘制圆形进度条(扩展性强!)_第2张图片

Android 自定义绘制圆形进度条(扩展性强!)_第3张图片

OK,上面三个图中,想必大家一看也都清楚了,分别有三种状态可以选择。大家也可以根据自己样式去修改。下面我将贴出源码。

RoundProgressBar.java

package com.qiulong.roundprogressbar;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
import com.qiulong.circlepregress.R;

/**
 * 自定义环形进度条
 * @author qiulong
 *
 */
@SuppressLint("DrawAllocation")
public class RoundProgressBar extends View {
	
	/** 默认圆环的画笔 */
	private Paint defaultRoundPaint;
	/** 圆环进度的画笔 */
	private Paint progresRoundPaint;
	/** 百分比字体的画笔 */
	private Paint percenTextPaint;
	/** 电量字体的画笔 */
	private Paint electriTextPaint;
	
	/** 默认圆环的背景颜色 */
	private int defaultRoundColor;
	/** 圆环进度的颜色 */
	private int roundProgressColor;
	/** 百分比字体颜色 */
	private int percenTextColor;
	/** 电量字体颜色 */
	private int electriTextColor;
	
	/** 百分比字体大小 */
	private float percenTextSize;
	/** 电量字体大小 */
	private float electriTextSize;
	/** 电量文字内容*/
	private String electriText;
	/** 是否显示电量文字(默认是不显示)*/
	private boolean showElectriText = false;
	
	/** 圆环进度的宽度 */
	private float roundWidth;
	/** 圆环进度的最大值,默认100 */
	private int max;
	/** 当前进度值 */
	private int progress;
	/** 圆弧的外轮廓矩形区域 */
	private RectF oval;
	
	/** 充电图标轨迹 */
	private Path chargingPath;
	/** 充电图标的颜色 */
	private int chargingColor;
	/** 是否显示充电图标(默认是不显示) */
	private boolean showChargingIcon = false;
	
	
	public RoundProgressBar(Context context) {
		this(context, null);
	}

	
	public RoundProgressBar(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}
	
	
	public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		//加载xml自定义属性
		TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);
		defaultRoundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_defaultRoundColor, Color.BLACK);
		roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
		percenTextColor = mTypedArray.getColor(R.styleable.RoundProgressBar_percenTextColor, Color.WHITE);
		percenTextSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_percenTextSize, 38);
		//充电文字内容
		electriText = context.getString(R.string.charging);
		electriTextColor = mTypedArray.getColor(R.styleable.RoundProgressBar_electriTextColor, Color.WHITE);
		electriTextSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_electriTextSize, 18);
		chargingColor = mTypedArray.getColor(R.styleable.RoundProgressBar_chargingColor, Color.GREEN);
		Util.dip2px(context, roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 15));
		max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
		mTypedArray.recycle();//使用缓存
		
		init();
	}
	
	
	/**
	 * 初始化
	 */
	private void init(){
		setLayerType(LAYER_TYPE_SOFTWARE, null);
		
		defaultRoundPaint = new Paint();
		defaultRoundPaint.setAntiAlias(true);
		defaultRoundPaint.setColor(defaultRoundColor); 
		defaultRoundPaint.setStyle(Paint.Style.STROKE); 
		defaultRoundPaint.setStrokeWidth(roundWidth); 
		
		progresRoundPaint = new Paint();
		progresRoundPaint.setAntiAlias(true);
		progresRoundPaint.setColor(roundProgressColor);
		progresRoundPaint.setStyle(Paint.Style.STROKE); 
		progresRoundPaint.setStrokeWidth(roundWidth);
		
		percenTextPaint = new Paint();
		percenTextPaint.setAntiAlias(true);
		percenTextPaint.setColor(percenTextColor);
		percenTextPaint.setStyle(Style.FILL);
		percenTextPaint.setTextSize(percenTextSize);
		
		electriTextPaint = new Paint();
		electriTextPaint.setAntiAlias(true);
		electriTextPaint.setColor(electriTextColor);
		electriTextPaint.setStyle(Style.FILL);
		electriTextPaint.setTextSize(electriTextSize);
	}
	
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//计算中心点
		int centre = getWidth() / 2;
		//计算半径
		int radius = (int) (centre - roundWidth / 2);
		//绘制默认环形进度
		canvas.drawCircle(centre, centre, radius, defaultRoundPaint); 
		
		//绘制环形进度
		if (oval == null) {
			oval = new RectF(centre - radius, centre - radius,
					centre + radius, centre + radius);
		}
		canvas.drawArc(oval, -90, 360 * progress / max, false, progresRoundPaint);
		
		//先判断是否是充电
		if(showChargingIcon){
			//绘制正在充电图标
			canvas.save();
			canvas.clipPath(drawPath(getWidth()));// 先画好轨迹
			canvas.drawColor(chargingColor);
			canvas.restore();
		}else{
			int Offset = 0;
			if(showElectriText){
				Offset = 30;
			}
			//绘制进度值文字
			int percent = progress * 100 / max; 
			float percenTextWidth = percenTextPaint.measureText(percent + "%");   
			canvas.drawText(percent + "%", centre - percenTextWidth / 2, 
					centre + (percenTextSize / 2) - Offset, percenTextPaint);
			
			if(showElectriText){
				//绘制电量文字
				float electriTextWidth = electriTextPaint.measureText(electriText);
				canvas.drawText(electriText, centre - electriTextWidth / 2, 
						centre + (electriTextSize / 2) + Offset, electriTextPaint);
			}
		}
	}
	
	
	/**
	 * 绘制充电图标轨迹
	 * @param width
	 */
	private Path drawPath(int width){
		int avg = width/12;
		if(chargingPath == null){
			chargingPath = new Path();
		}
		chargingPath.moveTo(avg * 7, avg * 2);
		chargingPath.lineTo((avg * 6)+(avg/2), avg * 5);
		chargingPath.lineTo(avg * 8, avg * 5);
		chargingPath.lineTo(avg * 5, avg * 10);
		chargingPath.lineTo((avg * 5)+(avg/2), avg * 7);
		chargingPath.lineTo(avg * 4, avg * 7);
		chargingPath.close();
		return chargingPath;
	}
	
	
	/**
	 * 设置圆形进度的最大值
	 * @param max
	 */
	public void setMax(int max) {
		if(max < 0){
			max = 100;//默认为100
		}
		this.max = max;
	}


	/**
	 * 设置进度值
	 * @param progress
	 */
	public void setProgress(int progress) {
		if(progress < 0){
			progress = 0;
		}
		if(progress > max){
			progress = max;
		}
		if(progress <= max){
			this.progress = progress;
			postInvalidate();
		}
	}
	

	/**
	 * 设置圆环进度的宽度
	 * @param roundWidth
	 */
	public void setRoundWidth(float roundWidth) {
		this.roundWidth = roundWidth;
	}
	
	
	/**
	 * 设置进度的背景颜色(底色)
	 * @param cricleColor
	 */
	public void setDefaultRoundColor(int cricleColor) {
		this.defaultRoundColor = cricleColor;
	}

	
	/**
	 * 设置进度的颜色
	 * @param roundProgressColor
	 */
	public void setRoundProgressColor(int roundProgressColor) {
		this.roundProgressColor = roundProgressColor;
	}

	
	/**
	 * 设置百分比字体的颜色
	 * @param percenTextColor
	 */
	public void setPercenTextColor(int percenTextColor) {
		this.percenTextColor = percenTextColor;
	}


	/**
	 * 设置百分比字体大小
	 * @param percenTextSize
	 */
	public void setPercenTextSize(float percenTextSize) {
		this.percenTextSize = percenTextSize;
	}

	
	/**
	 * 设置是否显示电量文字
	 * @param showElectriText
	 */
	public void setShowElectriText(boolean showElectriText){
		this.showElectriText = showElectriText;
		postInvalidate();
	}
	
	
	/**
	 * 设置是否显示充电图标
	 * @param showChargingIcon
	 */
	public void setShowChargingIcon(boolean showChargingIcon){
		this.showChargingIcon = showChargingIcon;
		postInvalidate();
	}
}

MainActivity.java类

package com.qiulong.roundprogressbar;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.qiulong.circlepregress.R;


public class MainActivity extends Activity {
	private RoundProgressBar mRoundProgressBar2;
	private Button btn1, btn2, btn3;
	
	private int progress = 0;
	private boolean running = false;
	private boolean one = true;
	private boolean two = true;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_cricle_progress);
		
		mRoundProgressBar2 = (RoundProgressBar) findViewById(R.id.roundProgressBar2);
		btn1 = (Button) findViewById(R.id.button1);
		btn2 = (Button) findViewById(R.id.button2);
		btn3 = (Button) findViewById(R.id.button3);
		
		btn1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if(!running){
					Init();
				}
			}
		});
		
		btn2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if(one){
					mRoundProgressBar2.setShowElectriText(true);
					one = false;
					btn2.setText("隐藏电量");
				}else{
					mRoundProgressBar2.setShowElectriText(false);
					one = true;
					btn2.setText("显示电量");
				}
			}
		});
		btn3.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if(two){
					mRoundProgressBar2.setShowChargingIcon(true);
					two = false;
					btn2.setText("隐藏图标");
				}else{
					mRoundProgressBar2.setShowChargingIcon(false);
					two = true;
					btn2.setText("显示图标");
				}
			}
		});
	}
	
	
	private void Init() {
		progress = 0;
		Thread s = new Thread(runble);
		s.start();
	}
	
	
	/** 用于更新UI进度及数据 */
	private Runnable runble = new Runnable() {
		public void run() {
			running = true;
			while (progress <= 83) {
				// 转换为360的百分比
				mRoundProgressBar2.setProgress(progress);
				progress++;
				try {
					Thread.sleep(30);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			running = false;
		}
	};
	
}

xml布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.qiulong.circlepregress"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/theme_background"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dip"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加载进度" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="显示电量" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="显示图标" />
    </LinearLayout>

    <com.qiulong.roundprogressbar.RoundProgressBar
        android:id="@+id/roundProgressBar2"
        android:layout_width="200dip"
        android:layout_height="200dip"
        android:layout_marginTop="30dip"
        app:chargingColor="@color/theme_green"
        app:defaultRoundColor="@color/down_background"
        app:electriTextColor="@color/white"
        app:electriTextSize="20sp"
        app:max="100"
        app:percenTextColor="@color/white"
        app:percenTextSize="48sp"
        app:roundProgressColor="@color/theme_green"
        app:roundWidth="20dip" />

</LinearLayout>

最后一个自定义属性xml文件

<?xml version="1.0" encoding="UTF-8"?>
<resources>

    <declare-styleable name="RoundProgressBar">
        <attr name="defaultRoundColor" format="color" />
        <attr name="roundProgressColor" format="color" />
        <attr name="roundWidth" format="dimension"></attr>
        <attr name="percenTextColor" format="color" />
        <attr name="percenTextSize" format="dimension" />
        <attr name="electriTextColor" format="color" />
        <attr name="electriTextSize" format="dimension" />
        <attr name="chargingColor" format="color" />
        <attr name="max" format="integer"></attr>
    </declare-styleable>

</resources>

OK!希望对大家有所帮助,不懂的朋友欢迎提问,下面是demo下载地址:

http://download.csdn.net/detail/baidu_23478311/8752507

转载请注明出处!


你可能感兴趣的:(android进度条,自定义圆形进度条,自定义圆环进度条,自定义绘制进度条)