一、attrs.xml
这进度条交替,涉及到一些属性,例如:进度条的颜色和速度等,这些属性是View里面没有的,所以需要自定义。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="firstColor" format="color" />
<attr name="secondColor" format="color" />
<attr name="circleWidth" format="dimension" />
<attr name="speed" format="integer" />
<declare-styleable name="CustomProgressBar">
<attr name="firstColor" />
<attr name="secondColor" />
<attr name="circleWidth" />
<attr name="speed" />
</declare-styleable>
</resources>
在上面的文件中,先声明几个属性,包含有属性的命名和属性值的单位。color表示颜色单位,可以引用系统颜色单位或者自定义颜色;dimensiion表示圆环的宽度单位可以是dp。
integer表示速度单位为1。属性名称也就是在引用该View的时候设置属性的名称。
每一个属性有一个唯一标识,就像id一样,获得的方法:R.styleable.CustomProgressBar_firstColor,其它的同理。
二、CustomProgressBar
package com.example.customerviewdemo2;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
public class CustomProgressBar extends View {
private int mFirstColor;// 第一圈的颜色
private int mSecondColor;// 第二圈的颜色
private int mCircleWidth;// 圈的宽度
private Paint mPaint;// 画笔
private int mProgress;// 当前进度
private int mSpeed;// 速度
private boolean isNext = false;// 是否应该开始下一个
public CustomProgressBar(Context context) {
this(context, null);
}
public CustomProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* 必要的初始化,获得一些自定义的值
*
* @param context
* @param attrs
* @param defStyle
*/
public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
/*读取attrs.xml文件,返回的是一个属性集合*/
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomProgressBar, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.CustomProgressBar_firstColor:
mFirstColor = a.getColor(attr, Color.BLUE);
break;
case R.styleable.CustomProgressBar_secondColor:
mSecondColor = a.getColor(attr, Color.RED);
break;
case R.styleable.CustomProgressBar_circleWidth:
/* 将20px单位转换成dp单位;因为在attrs.xml中定义的单位是format="dimension" */
int defaultValue = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, context.getResources().getDisplayMetrics());
mCircleWidth = a.getDimensionPixelSize(attr, defaultValue);
break;
case R.styleable.CustomProgressBar_speed:
mSpeed = a.getInt(attr, 20);// 默认速度是20,format="integer"
break;
}
}
a.recycle();
mPaint = new Paint();
// 绘图线程
new Thread() {
public void run() {
while (true) {
mProgress++;
if (mProgress == 360) {// 跑完一圈时,将mProgress置为0,重新开始跑
mProgress = 0;
if (!isNext)
isNext = true;
else
isNext = false;
}
postInvalidate();// 刷新界面
try {
Thread.sleep(mSpeed);// 按照速度,mProgress递增,并不断的刷新界面
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
@Override
protected void onDraw(Canvas canvas) {
int centre = getWidth() / 2; // 获取圆心的x坐标
int radius = centre - mCircleWidth / 2;// 半径
mPaint.setStyle(Paint.Style.STROKE); // 设置空心
mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度
mPaint.setAntiAlias(true); // 消除锯齿
RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限
if (!isNext) {// 第一颜色的圈完整,第二颜色跑
mPaint.setColor(mFirstColor); // 设置圆环的颜色
canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环
mPaint.setColor(mSecondColor); // 设置圆环的颜色
canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根据进度画圆弧
} else {
mPaint.setColor(mSecondColor); // 设置圆环的颜色
canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环
mPaint.setColor(mFirstColor); // 设置圆环的颜色
canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根据进度画圆弧
}
}
}
三、引用自定义的View
<LinearLayout 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.example.customerviewdemo2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.example.customerviewdemo2.CustomProgressBar
android:layout_width="100dp"
android:layout_height="100dp"
app:circleWidth="20dp"
app:firstColor="#F00"
app:secondColor="#0f0"
app:speed="20" >
</com.example.customerviewdemo2.CustomProgressBar>
<com.example.customerviewdemo2.CustomProgressBar
android:layout_width="100dp"
android:layout_height="100dp"
app:circleWidth="20dp"
app:firstColor="#2090C0"
app:secondColor="#C8F060"
android:layout_marginTop="10dp"
app:speed="20" >
</com.example.customerviewdemo2.CustomProgressBar>
</LinearLayout>
四、效果如下图: