Android自定义控件系列之应用篇——圆形进度条

ybny 10年前

一、概述

在上一篇博文中,我们给大家介绍了Android自定义控件系列的基础篇。链接:http://www.cnblogs.com/jerehedu/p/4360066.html 

这一篇博文中,我们将在基础篇的基础上,再通过重写ondraw()方法和自定义属性实现圆形进度条,效果如图所示:

Android自定义控件系列之应用篇——圆形进度条 Android自定义控件系列之应用篇——圆形进度条

二、实现步骤

         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);          }      }  }


来自:http://blog.csdn.net/jerehedu/article/details/45195711