一、概述
  在上一篇博文中,我们给大家介绍了Android自定义控件系列的基础篇。链接:http://www.cnblogs.com/jerehedu/p/4360066.html
  这一篇博文中,我们将在基础篇的基础上,再通过重写ondraw()方法和自定义属性实现圆形进度条,效果如图所示:
 

  二、实现步骤
  1、编写自定义组件MyCircleProgress扩展View
  public class MyCircleProgress extends View{
  …
  }
  2、在MyCircleProgress类中,定制属性
  public int progress=0;//进度实际值,当前进度
  /**
  *自定义控件属性,可灵活的设置圆形进度条的大小、颜色、类型等
  */
  private int mR;//圆半径,决定圆大小
  private int bgColor;//圆或弧的背景颜色
  private int fgColor;//圆或弧的前景颜色,即绘制时的颜色
  private int drawStyle;//绘制类型FILL画圆形进度条,STROKE绘制弧形进度条
  private int strokeWidth;//STROKE绘制弧形的弧线的宽度
  private int max;//大值,设置进度的大值
  /**
  *设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
  */
  public synchronized void setProgress(int progress){
  if(progress<0){
  progress=0;
  }else if(progress>max){
  progress=max;
  }else{
  this.progress=progress;
  }  
  }
  public int getMax(){
  return max; }
  3、为定制的属性编写attrs.xml资源,该资源文件放在res/values目录下,内容如下:
  <?xml version="1.0"encoding="utf-8"?>
  <resources>
  <declare-styleable name="CircleProgressBar">
  <attr name="bgColor"format="color"/>
  <attr name="fgColor"format="color"/>
  <attr name="r"format="integer"/>
  <attr name="strokeWidth"format="integer"/>
  <attr name="drawStyle">
  <enum name="STROKE"value="0"></enum>
  <enum name="FILL"value="1"></enum>
  </attr>
  <attr name="max"format="integer"/>
  </declare-styleable>
  </resources>
  4、在MyCircleProgress类中定义构造函数,初始化属性
  private void initProperty(AttributeSet attrs){
  TypedArray tArray=context.obtainStyledAttributes(attrs,R.styleable.CircleProgressBar);
  mR=tArray.getInteger(R.styleable.CircleProgressBar_r,10);
  bgColor=tArray.getColor(R.styleable.CircleProgressBar_bgColor,Color.GRAY);
  fgColor=tArray.getColor(R.styleable.CircleProgressBar_fgColor,Color.RED);
  drawStyle=tArray.getInt(R.styleable.CircleProgressBar_drawStyle,0);
  strokeWidth=tArray.getInteger(R.styleable.CircleProgressBar_strokeWidth,10);
  max=tArray.getInteger(R.styleable.CircleProgressBar_max,100);
  } 
  public MyCircleProgress(Context context,AttributeSet attrs){
  super(context,attrs);
  this.context=context;
  this.paint=new Paint();
  this.paint.setAntiAlias(true);//消除锯齿
  this.paint.setStyle(Style.STROKE);//绘制空心圆或空心矩形
  initProperty(attrs); 
  }
  5、在MainActivity中布局文件中添加MyCircleProgress组件,如下所示
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  xmlns:app="http://schemas.android.com/apk/res/com.jereh.mydrawcircleprogress"
  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"
  tools:context=".MainActivity"
  >
  <com.jereh.views.MyCircleProgress
  android:id="@+id/MyCircleProgress"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  app:r="45"
  app:strokeWidth="10"
  app:bgColor="#cccccc"
  app:fgColor="#ff0000"
  app:drawStyle="FILL"
  app:max="50"
  />
  </RelativeLayout>
  6、自定义组件MyCircleProgress中重写onDraw方法:
  protected void onDraw(Canvas canvas){
  super.onDraw(canvas);
  int center=getWidth()/2;//圆心位置
  this.paint.setColor(bgColor);
  this.paint.setStrokeWidth(strokeWidth);
  canvas.drawCircle(center,center,mR,this.paint);
  //绘制圆环
  this.paint.setColor(fgColor);
  if(drawStyle==0){
  this.paint.setStyle(Style.STROKE);
  opt=false;
  }else{
  this.paint.setStyle(Style.FILL);
  opt=true;
  }
  int top=(center-mR);
  int bottom=(center+mR);
  RectF oval=new RectF(top,top,bottom,bottom);
  canvas.drawArc(oval,270,360*progress/max,opt,paint);
  }
  7、编写MainActivity
  public class MainActivity extends Activity{
  private MyCircleProgress progressView;
  @Override
  protected void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  progressView=(MyCircleProgress)findViewById(R.id.MyCircleProgress);
  new ProgressAnimation().execute();
  }
  class ProgressAnimation extends AsyncTask<Void,Integer,Void>{
  @Override
  protected Void doInBackground(Void...params){
  //进度值不断的变化
  for(int i=0;i<progressView.getMax();i++){
  try{
  publishProgress(i);
  Thread.sleep(100);
  }catch(InterruptedException e){
  e.printStackTrace();
  }
  }
  return null;
  }
  @Override
  protected void onProgressUpdate(Integer...values){
  //更新进度值
  progressView.setProgress(values[0]);
  progressView.invalidate();
  super.onProgressUpdate(values);
  }
  }
  }