你的位置:首页 > 操作系统

[操作系统]Android自定义控件系列之应用篇——圆形进度条


一、概述

  在上一篇博文中,我们给大家介绍了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.

<??><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 ="http://schemas.android.com/apk/res/android"="http://schemas.android.com/tools"="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);    }  }}