本文主要是实现一个自定义的圆环,两种颜色交替进行,非百分之百原创,不喜勿喷。下面直接上干货。先上效果图:
1. 定义View的xml属性
自定义该View的属性,首先在res/values/下建立一个attrs.xml, 在里面定义我们的属性和声明我们的整个样式
<declare-styleable name="CustomCircleView">
<attr name="firstColor" format="color"/>
<attr name="secondColor" format="color"/>
<attr name="circleWidth" format="dimension"/>
<attr name="speed" format="integer"/>
</declare-styleable>
这里定义了firstColor,secondColor等属性,用于描述圆环的属性。
2. 定义CustomCircleView类
在构造方法中获取属性,这里主要是我们定义的上面三种属性。
public class CustomCircleView extends View{
private Context mContext;
private int mFirstColor;//第一种颜色
private int mSecondColor;//第二种颜色
private int mSpeed;//绘制的速度
private int mCircleWidth;//圆环的宽度
private int mProgress;//当前进度
private boolean isNext = false;//是否进行下一次绘制
private Paint mPaint;//画笔
public CustomCircleView(Context context){
this(context,null);
}
public CustomCircleView(Context context, AttributeSet attrs){
this(context,attrs,0);
}
public CustomCircleView(Context context,AttributeSet attrs,int defstyle){
super(context,attrs,defstyle);
mContext = context;
//获取xml属性
TypedArray array = mContext.obtainStyledAttributes(attrs, R.styleable.CustomCircleView);
//默认黑色
mFirstColor = array.getColor(R.styleable.CustomCircleView_firstColor, Color.BLACK);
//默认绿色
mSecondColor = array.getColor(R.styleable.CustomCircleView_secondColor,Color.GREEN);
//默认20dp
mCircleWidth = (int)array.getDimension(R.styleable.CustomCircleView_circleWidth,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,20,getResources().getDisplayMetrics()));
mSpeed = array.getInteger(R.styleable.CustomCircleView_speed,10);
//回收TypeArray
array.recycle();
mPaint = new Paint();
//设置抗锯齿
mPaint.setAntiAlias(true);
……
}
}
这里主要是获取xml文件中的属性,初始化Paint等。
3. 重写onDraw ()方法
该方法的主要目的就是画一个圆环,并使用不同的颜色等。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取圆心
int center = getWidth() / 2;
//半径
int radius = center - mCircleWidth / 2;
//设置圆环宽度
mPaint.setStrokeWidth(mCircleWidth);
//设置空心
mPaint.setStyle(Paint.Style.STROKE);
//定义圆弧的形状和大小的界限
RectF rectF = new RectF(center - radius,center - radius,center + radius,center + radius);
if (!isNext){
//第一圈的颜色完整,第二圈开始跑
//设置圆环颜色
mPaint.setColor(mFirstColor);
//画圆
canvas.drawCircle(center,center,radius,mPaint);
//设置第二圈颜色
mPaint.setColor(mSecondColor);
//根据进度画圆弧
canvas.drawArc(rectF,0,mProgress,false,mPaint);
} else {
//第二圈的颜色完整,第一圈开始跑
//设置圆环颜色
mPaint.setColor(mSecondColor);
//画圆
canvas.drawCircle(center,center,radius,mPaint);
//设置第一圈颜色
mPaint.setColor(mFirstColor);
//根据进度画圆
canvas.drawArc(rectF,0,mProgress,false,mPaint);
}
}
onDraw方法中主要是绘制圆环,以第一种颜色绘制圆环,然后保持半径和圆心相同再绘制圆弧,绘制的角度是mProgress,当mProgress为360时,就代表全部绘制完了,这个时候就需要进行是否绘制第二次的判断了。经过分析,我们知道,我们需要多次间隔的改变mProgress的值,从而调用onDraw()方法才能达成我们想要的结果。因此我们需要建立一个后台线程来改变mProgress的值。
4. 完善CustomCircleView
在构造方法中构造一个线程,周期的改变mProgress的值。
//开启一个线程来改变progress的值
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
mProgress++;
if (mProgress == 360) {
mProgress = 0;
//将isNext反置
if (!isNext) {
isNext = true;
} else {
isNext = false;
}
}
//重新绘制
postInvalidate();
try {
Thread.sleep(mSpeed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
这样我们每次休眠mSpeed后,就改变mProgress的值。再调用postInvalidate()使onDraw()方法调用就会重新绘制了。
5. 使用CustomCircleView
直接在布局文件中引入自定义的View。
<com.customview.ui.CustomCircleView
android:layout_width="match_parent"
android:layout_height="match_parent"
custom:firstColor="@color/colorPrimaryDark"
custom:secondColor="@color/colorAccent"
custom:speed="10"
custom:circleWidth="100dp"/>
最后的效果如最开始给的图。