您的位置:首页 > 移动开发 > Android开发

Android自定义环形ProgressBar

2015-01-23 16:13 211 查看
在项目中有个需求,要实现如下图所示的进度条:



下面我们就用自定义的View来实现它。

package cn.yubo.roundprogress;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 自定义圆环进度条
 * @author yubo<br/>
 * 2015年1月23日
 */
public class RoundProgressView extends View {
	private int centerX;//圆环的中心X坐标
	private int centerY;//圆环的中心Y坐标
	private int radius;//圆环的半径
	private Paint paint;//圆环的画笔
	private Paint progressPaint;//圆环中进度的画笔
	private int progress;//当前进度
	private int maxProgress = 100;//最大进度,默认为100

	public RoundProgressView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public RoundProgressView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public RoundProgressView(Context context) {
		super(context);
		init();
	}
	
	/**创建RoundProgressView时通过该方法初始化*/
	private void init(){
		paint = new Paint();
		paint.setStrokeWidth(20);
		paint.setStyle(Paint.Style.STROKE);
		paint.setAntiAlias(true);
		paint.setColor(Color.parseColor("#E7E7E7"));//灰色的圆环
		
		progressPaint = new Paint();
		progressPaint.setAntiAlias(true);                       
		progressPaint.setColor(Color.parseColor("#1082F5"));//蓝色的进度                    
		progressPaint.setStrokeWidth((float) 20.0);            
		progressPaint.setStyle(Style.STROKE); 
		progressPaint.setStrokeCap(Paint.Cap.ROUND);//让画笔画出的线条是圆的
	}
	
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		//计算圆环的圆心坐标
		centerX = getMeasuredWidth() / 2;
		centerY = getMeasuredHeight() / 2;
		//计算圆环的半径,这里取View的长宽中较小值的1/2
		radius = (centerX > centerY ? centerY : centerX) / 2;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//画出灰色的圆环
		canvas.drawCircle(centerX, centerY, radius, paint);
		//构造圆环的外围矩形
		RectF rectF = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
		//计算显示的进度
		int progressAngle = (progress * 360) / maxProgress;
		//画出进度,注意这里的270表示从圆环的最顶部开始画,如果270替换为0,则是从圆环的右端开始画
		canvas.drawArc(rectF, 270, progressAngle, false, progressPaint);
	}
	
	public int getProgress() {
		return progress;
	}

	public void setProgress(int progress) {
		this.progress = progress;
		postInvalidate();
	}

	public int getMaxProgress() {
		return maxProgress;
	}

	public void setMaxProgress(int maxProgress) {
		this.maxProgress = maxProgress;
	}

}


在布局文件中,我们这么使用上面的类:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <cn.yubo.roundprogress.RoundProgressView
        android:id="@+id/roundProgress"
        android:layout_width="fill_parent"
        android:layout_height="300dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

</RelativeLayout>


然后是Activity中:

package cn.yubo.roundprogress;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {
	private RoundProgressView roundProgress;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		roundProgress = (RoundProgressView) findViewById(R.id.roundProgress);
		roundProgress.setProgress(35);
	}

}


运行的效果如下图:



这里需要注意的一些地方是:

1、只有设置了如下方法,才能使绘制的进度条两头是圆的

progressPaint.setStrokeCap(Paint.Cap.ROUND);//让画笔画出的线条是圆的
如果没有设置Paint的该属性,则绘出来的效果如下:



2、要注意Canvas的drawArc方法,该方法用于画一段圆弧,其构造方法中的RectF参数,指定了所画圆弧的外边缘区域,后面两个参数指定绘制的初始位置和绘制的角度,比如上例中,初始位置为270,则会从圆环的顶部开始绘制,角度为30的话,则会从顶部开始绘制30度,drawArc接下来的一个参数为boolean值,为true时会画出圆弧的中央部分,为false时则只绘制圆弧的边缘,drawArc的最后一个参数为画笔Paint对象,这里就不用多说了

下面上两张图用来说明drawArc方法:





上面图1对应的代码是:

RectF oval = new RectF(x - radius, y - radius, x + radius, y + radius);
canvas.drawArc(oval, 0, 90, false, paint);
图2对应的代码是:

RectF oval = new RectF(x - radius, y - radius, x + radius, y + radius);
canvas.drawArc(oval, 0, 90, true, paint);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: