首先我们先来看一下效果
分析
我们来看这个进度条应该分为3个小部分
1.中间的圆
2.外边的圆环
3.中间的文字
分开画
这3部分就是需要我们自己画出来的,因此我们需要3根画笔
//设置中心园的画笔
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(mCircleBackground);
mCirclePaint.setStyle(Paint.Style.FILL);
//设置文字的画笔
mTextPaint = new Paint();
mTextPaint.setColor(mTextColor);
mTextPaint.setAntiAlias(true);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setStrokeWidth((float) (0.025*mRadius));
mTextPaint.setTextSize(mRadius/2);
mTextPaint.setTextAlign(Align.CENTER);
//设置外圆环的画笔
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setColor(mRingColor);
mArcPaint.setStyle(Paint.Style.STROKE);
mArcPaint.setStrokeWidth((float) (0.075*mRadius));
接下来我们应该在onDraw里面画这3个部分,中间圆和文字都很好画,难点在于外面的圆环应该怎么画呢?
要想画圆环,首先我们现在new出一个矩形
//画中心园的外接矩形,用来画圆环用
mArcRectF = new RectF(mCircleX-mRadius, mCircleY-mRadius, mCircleX+mRadius, mCircleY+mRadius);
这个矩形就是圆环的外接矩形,也就是说圆环是这个矩形的内切圆,这样说有点抽象,我们在画布上把这个矩形画出来大家就明白了。
canvas.drawRect(mCircleX-mRadius, mCircleY-mRadius, mCircleX+mRadius, mCircleY+mRadius,mArcPaint);
看!就是这个矩形,接下来我们在画圆环的时候,这个矩形要作为第一个参数,这样系统就知道如何画这个圆环了,第二个参数为起始的角度,-90读为正北方向。第三个参数为当前的角度,第四个参数false即可,第五个参数就是画笔
//画圆环
canvas.drawArc(mArcRectF, mStartSweepValue ,mCurrentAngle, false, mArcPaint);
好了,最难的一个部分画完了,剩下的中间圆和文字就简单了
//画中间圆
canvas.drawCircle(mCircleX, mCircleY, mRadius, mCirclePaint);
//画文字
canvas.drawText(String.valueOf(mCurrentPercent)+"%", mCircleX, mCircleY+mTextSize/4, mTextPaint);
为了让进度条动起来,我们肯定要修改他的属性,也就是修改他的当前角度,然后再重画,这样圆就动起来了
//判断当前百分比是否小于设置目标的百分比
if (mCurrentPercent<mTargetPercent) {
//当前百分比+1
mCurrentPercent+=1;
//当前角度+360
mCurrentAngle+=3.6;
//每10ms重画一次
postInvalidateDelayed(10);
}
在values/attr下添加自定义属性
<resources>
<declare-styleable name="PercentageRing">
<attr name="radius" format="integer"/>
<attr name="circleBackground" format="color"/>
<attr name="ringColor" format="color"/>
<attr name="textColor" format = "color"/>
</declare-styleable>
</resources>
我们自定义了4个属性
1.radius 半径 类型为整形
2.circleBackground 中心园背景颜色 类型为color
3.ringColor 外圆环的颜色 类型为color
4.textColor 文字颜色 类型为color
然后在带有两个参数的构造方法中获取我们自定义属性
public PercentageRing(Context context, AttributeSet attrs) {
super(context, attrs);
//自定义属性 values/attr
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.PercentageRing);
//中间圆的背景颜色 默认为浅紫色
mCircleBackground = typedArray.getColor(R.styleable.PercentageRing_circleBackground, 0xffafb4db);
//外圆环的颜色 默认为深紫色
mRingColor = typedArray.getColor(R.styleable.PercentageRing_ringColor, 0xff6950a1);
//中间圆的半径 默认为60
mRadius = typedArray.getInt(R.styleable.PercentageRing_radius, 60);
//字体颜色 默认为白色
mTextColor = typedArray.getColor(R.styleable.PercentageRing_textColor, 0xffffffff);
//最后一定要调用这个 释放掉TypedArray
typedArray.recycle();
}
我们在xml中可以为进度条设置属性
<com.zhangqi.percentagecircle.PercentageRing
android:id="@+id/Circle2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:radius="50"
app:circleBackground="#ff43CD80"
app:ringColor="#ff3cb371"
app:textColor="#ffffffff"
/>
使用起来非常简单
我们只需要在Activity中获取到实例然后设置一个目标百分比就可以了
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPercentageRing1 = (PercentageRing) findViewById(R.id.Circle);
//设置目标百分比为30
mPercentageRing1.setTargetPercent(30);
mPercentageRing2 = (PercentageRing) findViewById(R.id.Circle2);
//设置目标百分比为50
mPercentageRing2.setTargetPercent(50);
mPercentageRing3 = (PercentageRing) findViewById(R.id.Circle3);
//设置目标百分比为70
mPercentageRing3.setTargetPercent(70);
mPercentageRing4 = (PercentageRing) findViewById(R.id.Circle4);
//设置目标百分比为100
mPercentageRing4.setTargetPercent(100);
}
}
完整代码
完整代码的注释很清楚,我就不贴出来了,大家可以上我的GitHub上面下载完整代码