自定义view之一-----圆形进度条

     现在这个项目,有一个圆形进度条的动画比较有意思,这个demo,是我结合网上的一篇博文和公司同事写的自定义控件写的。可以和大家分享一下:

一:动画效果:



二:源码:

(1)res/values/attrs.xml

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

(2)RoundProgressBar01.java

package com.example.roundprogressbar;

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;  

//博客地址:http://blog.csdn.net/xiaanming/article/details/10298163

public class RoundProgressBar01 extends View{
	private final static String TAG = "RoundProgressBar01";
	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 RoundProgressBar01(Context context) {  
        this(context, null);  
    }  
	  
    public RoundProgressBar01(Context context, AttributeSet attrs) {  
        this(context, attrs, 0);  
    }  
	      
    public RoundProgressBar01(Context context, AttributeSet attrs, int defStyle) {  
        super(context, attrs, defStyle);         
        
        init(context,attrs); 
    }  	      	  

    private void init(Context context, AttributeSet attrs) {
		// TODO Auto-generated method stub
    	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_textColor, Color.GREEN);  
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);  
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 20);  
        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(); 		
	}

	protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        Log.i(TAG, "RoundProgressBar01--onDraw");
        
        /** 
         * 画最外层的大圆环 
         */  
        int centre = getWidth()/2; //获取圆心的x坐标  
        int radius = (int) (centre - roundWidth/2); //圆环的半径  
        Log.i(TAG, "onDraw:"+"centre:"+centre+"--radius:"+radius);
        paint.setColor(roundColor); //设置圆环的颜色  
        paint.setStyle(Paint.Style.STROKE); //设置空心  
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度  
        paint.setAntiAlias(true);  //消除锯齿   
        canvas.drawCircle(centre, centre, radius, paint); //画出圆环           
          
        /** 
         * 画进度百分比 
         */  
        paint.setStrokeWidth(0);   
        paint.setColor(textColor);  
        paint.setTextSize(textSize);  
        paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体  
        //中间的进度百分比,先转换成float在进行除法运算,不然都为0  
        int percent = (int)(((float)progress / (float)max) * 100);
        //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
        float textWidth = paint.measureText(percent + "%");     
        Log.i(TAG, "onDraw:"+"textIsDisplayable:"+textIsDisplayable+"--percent:"+percent+"--style == STROKE:"+(style == STROKE));  
        //if(textIsDisplayable && percent != 0 && style == STROKE){
        if(textIsDisplayable && style == STROKE){
        	//画出进度百分比
            canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize/2, paint);   
        }           
          
        /** 
         * 画圆弧 ,画圆环的进度 
         */  
          
        //设置进度是实心还是空心  
        paint.setStrokeWidth(roundWidth); //设置圆环的宽度  
        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;  
    }  
    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 progress;  
    }  
  
    public synchronized void setProgress(int progress) {  
        if(progress < 0){  
            throw new IllegalArgumentException("progress not less than 0");  
        }  
        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;  
    }  
	public synchronized void setStyle(int style){
		this.style = style;
	}    
}

(3)RoundProgressBar.java

package com.example.roundprogressbar;

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.graphics.Typeface;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class RoundProgressBar extends View{
	
	private final static String TAG = "RoundProgressBar";
	
	private Paint paint ;
	private int roundColor;
	private int roundProgressColor;
	private int textColor;
	private float textSize;
	private float roundWidth;
	private int max;
	private float progress;
	private boolean textIsDisplayable;
	private int style;
	private int digree1 = 0;
	private String time ="";
	private int lastTime = 0;
	private int pointWidth = 4;
	public static final int TIME_TICKER = 0;
	public static final int PROGRESS = 1;
	private float progressStep = (float) 0.1;
	
	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);
		// TODO Auto-generated constructor stub
		init(context,attrs);		
		//tickerHandler.sendMessageDelayed(tickerHandler.obtainMessage(1), 1000);
	}
	
	private void init(Context context, AttributeSet attrs) {
		// TODO Auto-generated method stub
		paint =new Paint();	
		TypedArray mTypeArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);
		roundColor = mTypeArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
		roundProgressColor = mTypeArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
		textColor = mTypeArray.getColor(R.styleable.RoundProgressBar_textColor,Color.GREEN);
		textSize = mTypeArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
		roundWidth = mTypeArray.getDimension(R.styleable.RoundProgressBar_roundWidth,5);
		max = mTypeArray.getInteger(R.styleable.RoundProgressBar_max, 60);
		textIsDisplayable = mTypeArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
		style = mTypeArray.getInt(R.styleable.RoundProgressBar_style, 0);
		progress = 0.0f;
		mTypeArray.recycle();
	}

//	Handler tickerHandler = new Handler(){	 
//		@Override
//		public void handleMessage(Message msg) {
//		// TODO Auto-generated method stub
//			super.handleMessage(msg);
//			switch(msg.what){
//				case 1:
//				invalidate();
//				break;
//				case 2:
//				invalidate();
//				break;
//			}
//		}
//	};
	
	@Override
	protected void onDraw(Canvas canvas){
		Log.i(TAG, "RoundProgressBar--onDraw");
		int centre = getWidth()/2;
		int padding = 10;
		int radius = (int)(centre-roundWidth/2)-padding;
		Rect rect = new Rect();
		 
		paint.setColor(roundColor);
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(roundWidth);
		paint.setAntiAlias(true);
		paint.setTextSize(textSize);
		paint.setAlpha(180);

		 
		switch(style){
			case TIME_TICKER:
			{
				float tl = paint.measureText(time)+padding;
				float arc = (float)Math.asin(tl/2/radius);
				float arc_b = (float)Math.toDegrees(arc);
				RectF oval_1 = new RectF(centre-radius,centre-radius,centre+radius,centre+radius);
				//canvas.drawArc(oval_1, (-90+arc_b), (360-2*arc_b), false, paint);
				canvas.drawArc(oval_1, 0, 360, false, paint);
				//paint.setStrokeWidth(roundWidth);
				paint.setColor(roundProgressColor);
				//paint.setAlpha(0);
				if(lastTime == (int)progress)
					progress += progressStep;
				if(progress > 100)
					progress = 0;
				RectF oval = new RectF(centre-radius,centre-radius,centre+radius,centre+radius);
				//canvas.drawArc(oval, (-90+arc_b), (360-2*arc_b)*progress/max, false, paint);
				canvas.drawArc(oval, -90, 270*progress/max, false, paint);
				paint.setStrokeWidth(0);
				paint.setColor(textColor);
				paint.setTextSize(textSize);
				paint.setTypeface(Typeface.DEFAULT_BOLD);
				float textWidth = paint.measureText(time);
				paint.getTextBounds(time, 0, time.length(), rect);
				int textheight = rect.height();
				canvas.drawText(time, centre-textWidth/2,centre+textheight/2,paint);
				this.lastTime = (int)progress;
				//tickerHandler.sendMessageDelayed(tickerHandler.obtainMessage(1), 100);
				invalidate();
				break;
				}
			case PROGRESS:
			{
				int x1,y1;				 
				canvas.drawCircle(centre, centre, radius, paint);
				if (digree1 > 360)
					digree1 = 0;
				else if(digree1>335)
					digree1 +=3;
				else if(digree1>305)
					digree1+=2;
				else if(digree1 >270)
					digree1 +=1;
				else if(digree1>225)
					digree1 +=3;
				else if(digree1 >180)
					digree1 +=4;
				else if(digree1>135 )
					digree1 +=7;
				else if(digree1 >90)
					digree1 +=10;
				else if(digree1>45)
					digree1 +=10;
				else 
					digree1 +=7;
				x1 =(int)(centre+radius*Math.cos(digree1*Math.PI/180));
				y1 = (int)(centre+radius*Math.sin(digree1*Math.PI/180));
				paint.setStyle(Style.FILL);
				canvas.drawCircle(x1, y1, roundWidth+pointWidth, paint);
				invalidate();
				break;
			}
		}
	}
 
	public synchronized void setTime(String time,int progress){
		this.time = time;
		this.progress = progress;
	}
	
	public synchronized void setPointWidth(int pointWidth){
		this.pointWidth = pointWidth;
	}	
	
	public synchronized void setStyle(int style){
		this.style = style;
	}
	
	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 float getProgress(){
		return progress;
	}
	public synchronized void setProgress(int progress){
		if(progress<0){
			throw new IllegalArgumentException("progress not less than 0");
		}
		if(progress>max){
			progress = max;
		}
		if(progress<=max){
			this.progress = progress;
			postInvalidate();
		}
	}
	public int getCricelColor(){
		return roundColor;
	}
	public int getCricelProgressColor(){
		return roundProgressColor;
	}
	public void setCircleProgressColor(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 void setProgressStep(float progressStep){
		this.progressStep = progressStep;
	}	
	
	public float getRoundWidth(){
		return roundWidth;
	}
	public void setRoundWidth(float roundWidth){
		this.roundWidth = roundWidth;
	}
}

(4)布局文件:res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom_progress="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    >
 
<com.example.roundprogressbar.RoundProgressBar01 
        android:id="@+id/roundProgressBar_01"
        android:layout_width="80dip"    
        android:layout_height="80dip"                                   
        custom_progress:roundColor="#3300d1d1"    
        custom_progress:roundProgressColor="@android:color/black"    
        custom_progress:textColor="#9A32CD"    
        custom_progress:textIsDisplayable="true"    
        custom_progress:roundWidth="10dip"    
        custom_progress:textSize="18sp"   
    />  
    
<com.example.roundprogressbar.RoundProgressBar01 
        android:id="@+id/roundProgressBar_04"
        android:layout_width="80dip"    
        android:layout_height="80dip"  
        android:layout_toRightOf="@id/roundProgressBar_01"                                 
        custom_progress:roundColor="#3300d1d1"    
        custom_progress:roundProgressColor="@android:color/black"    
        custom_progress:textColor="#9A32CD"    
        custom_progress:textIsDisplayable="true"    
        custom_progress:roundWidth="10dip"    
        custom_progress:textSize="18sp"  
        custom_progress:style="PROGRESS"
    />  
           
 <com.example.roundprogressbar.RoundProgressBar
    android:id="@+id/roundProgressBar_02"
    android:layout_below="@id/roundProgressBar_01"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_gravity="center"
    custom_progress:roundColor="#3300d1d1"
    custom_progress:roundProgressColor="@android:color/white"
    custom_progress:textColor="#FFFFFF"
    custom_progress:textIsDisplayable="true"
    custom_progress:roundWidth="1dip"
    custom_progress:textSize="12sp"
    custom_progress:style="PROGRESS"
	/> 
	
  <com.example.roundprogressbar.RoundProgressBar
    android:id="@+id/roundProgressBar_03"
    android:layout_below="@id/roundProgressBar_02"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_gravity="center"
    custom_progress:roundColor="#3300d1d1"
    custom_progress:roundProgressColor="@android:color/white"
    custom_progress:textColor="#9A32CD"
    custom_progress:textIsDisplayable="true"
    custom_progress:roundWidth="1dip"
    custom_progress:textSize="12sp"
    custom_progress:style="TIME_TICKER"
	/> 
</RelativeLayout>

(5):MainActivity.java

package com.example.roundprogressbar;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.app.Activity;

public class MainActivity extends Activity {
	
	private final static String TAG = "MainActivity";
	
	private RoundProgressBar01 roundProgressBar_01 = null;
	private RoundProgressBar roundProgressBar_02 = null;
	private RoundProgressBar roundProgressBar_03 = null;
    private int TIME_TICKER = 0;
    private int PROGRESS = 1;
	 
    private int time = 0;
    private int progress = 0;
    private final int UPDATE_UI_01 = 1;
    private final int UPDATE_UI_02 = 2;   
	
	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);			
			
			switch(msg.what){
				case UPDATE_UI_01:
					Log.i(TAG, "UPDATE_UI_01");
					progress++;
					if(progress > 100){
						progress = 0;
					}
					handler.sendEmptyMessageDelayed(UPDATE_UI_01, 1000);
					updateUIRoundProgressBar_01(progress);
					break;				
				case UPDATE_UI_02:
					Log.i(TAG, "UPDATE_UI_02");
					time++;
					if(time >= 100)
						time = 0;
					handler.sendEmptyMessageDelayed(UPDATE_UI_02, 1000);
					updateUI_02(time);
					break;
			}
		}		
	};
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
		handler.sendEmptyMessageDelayed(UPDATE_UI_01, 1000);
		//handler.sendEmptyMessageDelayed(UPDATE_UI_02, 1000);

	}

	private void init() {
		// TODO Auto-generated method stub
		roundProgressBar_01 = (RoundProgressBar01)findViewById(R.id.roundProgressBar_01);
		roundProgressBar_01.setStyle(TIME_TICKER);
		roundProgressBar_01.setProgress(1);
		progress = 1;		
		
		roundProgressBar_02 = (RoundProgressBar)findViewById(R.id.roundProgressBar_02);
		roundProgressBar_02.setStyle(PROGRESS);
		
		roundProgressBar_03 = (RoundProgressBar)findViewById(R.id.roundProgressBar_03);
		roundProgressBar_03.setStyle(TIME_TICKER);
		roundProgressBar_03.setTime("test:"+progress, progress);	
	}
	
	private void updateUI_02(int time){
		//roundProgressBar_02.setTime("test"+time,time);		
	}
	private void updateUI_03(String time,int progress){
		roundProgressBar_03.setTime("test"+time, progress);		
	}	
	private void updateUIRoundProgressBar_01(int progress){
		roundProgressBar_01.setProgress(progress);
	}
}


三:源码下载地址:

http://download.csdn.net/download/hfreeman2008/8202741


四:参考资料:

1.Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

http://blog.csdn.net/xiaanming/article/details/10298163

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hfreeman2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值