参考http://blog.csdn.net/lmj623565791/article/details/24500107
首先是自定义属性(至于为什么自定义属性,我暂且只知道可以定义一些没有的属性来使用,给变量赋值)
<?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>
上面定义了第一颜色,第二颜色,圆环的宽度,变换的速度
然后是自定义类
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);
}
public CustomProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取属性数组,其中省略getTheme()后效果一样,不知道是什么作用
TypedArray a=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomProgressBar,defStyleAttr,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.GREEN);
break;
case R.styleable.CustomProgressBar_secondColor:
mSecondColor=a.getColor(attr,Color.RED);
break;
case R.styleable.CustomProgressBar_circleWidth:
//TypedValue.applyDimension是一个标准转换函数
//getResources().getDisplayMetrics()表示的是获取手机分辨率的类
mCircleWidth=a.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,20,getResources().getDisplayMetrics()));
break;
case R.styleable.CustomProgressBar_speed:
mSpeed=a.getInt(attr,20);
break;
}
}
a.recycle();
mPaint=new Paint();
//绘图线程
new Thread(){
@Override
public void run() {
while (true){
mProgress++;
if(mProgress==360){
mProgress=0;
if(!isNext){
isNext=true;
}else{
isNext=false;
}
}
//在线程中使用更新UI,最后仍然会调用Invalidate(),即调用onDraw()方法
postInvalidate();
try {
Thread.sleep(mSpeed);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
@Override
protected void onDraw(Canvas canvas) {
int centre=getWidth()/2;
int centre2=getHeight()/2;
int radius=centre-mCircleWidth/2;//半径
mPaint.setStrokeWidth(mCircleWidth);//设置线宽
mPaint.setAntiAlias(true);//消除锯齿
mPaint.setStyle(Paint.Style.STROKE);//设置为空心
//设定一个圆弧的边界矩形
RectF oval=new RectF(centre-radius,centre2-radius,centre+radius,centre2+radius);
// if(!isNext){
mPaint.setColor(mFirstColor);
//注意这个设置的线宽是以半径长度为中线,两边扩展
canvas.drawCircle(centre,centre2,radius,mPaint);
mPaint.setColor(mSecondColor);
//第一个参数为边界矩形,第二个为起始角度,第三个为旋转角度,第四个是否画半径边,第五的为画笔
canvas.drawArc(oval,270,mProgress,false,mPaint);
// }
}
}
说一下上面类的大致思路:先是获取资源属性的值给变量,然后画第一层圆环,而第二层是圆弧,其中旋转角度的值由开启的线程来改变。
最后在布局中使用
加上一句
xmlns:molu="http://schemas.android.com/apk/res-auto"
然后使用
<com.example.administrator.customview03.CustomProgressBar
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
molu:circleWidth="50dp"
molu:firstColor="#D4F668"
molu:secondColor="#2F9DD2"
molu:speed="30"/>
摘抄一段drawArc()的解释
drawArc方法:绘制圆弧
【功能说明】该方法用于在画布上绘制圆弧,通过指定圆弧所在的椭圆对象、起始角度、终止角度来实现。该方法是绘制圆弧的主要方法。
【基本语法】public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
参数说明
oval:圆弧所在的椭圆对象。
startAngle:圆弧的起始角度。
sweepAngle:圆弧的角度。
useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示。
paint:绘制时所使用的画笔。
见 http://book.51cto.com/art/201204/328276.htm
导入一个图,解释一下上面半径的求解