一、概述 在上一篇博文中,我们给大家介绍了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); } } }