先上效果图:
自定义View绘制进度条:
package com.example.test; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Paint.Cap; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.View; public class MyCircle extends View { private static int DIAMETER = 0x5D; //Diameter英文为直径,该常量表示小圆直径的dp值 private static int STROKE_WIDTH = 0x1B; // 该常量表示圆环宽度2倍的dp值 private Paint mPaint; private int mProgress;// 表示进度 private RectF mRect; private int mDiameter; // Diameter英文为直径,在该View中要绘制圆环,圆环由两个圆形确定(大圆和小圆),这个整形值表示小圆直径。 private int mWidth;// 这个值表示圆环的宽度的2倍(大圆直径-小圆直径) private final int defaultColor; //进度条背景颜色 private final int processColor; //进度条进度颜色 public MyCircle(Context context, AttributeSet attrs) { super(context, attrs); int id = attrs.getAttributeResourceValue( "http://schemas.android.com/apk/res/android", "color", R.color.defaultColor); defaultColor = getResources().getColor(id); id = attrs.getAttributeResourceValue( "http://schemas.android.com/apk/res/android", "color", R.color.processColor); processColor = getResources().getColor(id); init(); } private void init() { Resources res = getResources(); //getDisplayMetrics()返回当前展示的metrics. DisplayMetrics metrics = res.getDisplayMetrics(); //TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics) //该方法中unit表示要转换成的单位,value表示数值,metrics表示当前的度量方式 //DIAMETER是常量0x1E,十进制为30,下面语句就表示tmp的值为30dp换算成的像素数值 float tmp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DIAMETER, metrics); //ceil函数表示向上取整 mDiameter = (int) Math.ceil(tmp); tmp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, STROKE_WIDTH, metrics); mWidth = (int) Math.ceil(tmp); Paint p = new Paint(); //Paint.Style.STROKE表示空心,Paint.Style.FILL表示实心,Paint.Style.FILL_AND_STROKE表示空心与实心 p.setStyle(Paint.Style.STROKE); p.setAntiAlias(true); //setStrokeWidth()设置画笔宽度 // p.setStrokeWidth(0.5F*mWidth+0.5F*mDiameter); p.setStrokeWidth(0.5F*mWidth); p.setStrokeCap(Cap.ROUND); p.setColor(defaultColor); mPaint = p; float rightTop = (float) (mWidth / 2.0);//这个值就是圆环宽度(大圆半径-小圆半径) mRect = new RectF(rightTop, rightTop, mDiameter+rightTop, mDiameter+rightTop); mProgress = 0; } @Override protected void onDraw(Canvas canvas) { // super.onDraw(canvas); Paint paint = mPaint; //如果mProgress<360,则圆形进度条还未旋转完成,则用0x7f的透明度绘制一个完整的圆形作为进度条背景 //注意要先绘制背景条,再绘制进度条,因为后绘制的会覆盖在先绘制的上面 if (mProgress < 360) { paint.setAlpha(0x7f); paint.setColor(defaultColor); canvas.drawArc(mRect, 135, 270, false, paint); } if (mProgress != 0) { float degree = (float) (270.0f * mProgress / 360); paint.setAlpha(0xff); paint.setColor(processColor); //drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) //该方法参数: //oval表示绘制椭圆的矩形边界; //startAngle表示起始角度; //useCenter //paint表示要使用的画笔; canvas.drawArc(mRect, 135, degree, false, paint); } } @Override protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //mDiameter表示小圆直径,mWidth表示圆环宽度的2倍,所以meas表示大圆直径 //所以View的hight,width都为meas final int meas = mDiameter + mWidth; setMeasuredDimension(meas, meas); } public void setProgress(int p) { mProgress = p; invalidate(); } public void postProgress(final int p) { post(new Runnable(){ @Override public void run() { setProgress(p); } }); } }
布局文件太简单,不给了,activity也很简单:
public class MainActivity extends Activity { ViewPager devPager,roomPager,devItemPager; MyCircle myCircle; int mProgress = 1; @SuppressLint("HandlerLeak") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search_device_new_diaolog); myCircle = (MyCircle)findViewById(R.id.search_device_new_customcircle); final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub if(msg.what == 0x1223) { myCircle.setProgress(mProgress); } } }; new Timer().schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub Message msg = new Message(); msg.what = 0x1223; if(mProgress < 360) { mProgress++; } else { this.cancel(); } handler.sendMessage(msg); } }, 0, 500); } }