Android自定义View的学习是初级开发到中级开发的一个重要学习内容。今天就自己做一个自定义小控件。该控件为圆环百分比显示,并显示绘画的过程动画。
自定义View开发步骤:
①自定义View的属性; ②在View的构造方法中构造我们的自定义View; ③重写onMeasure(); ④重写onDraw();⑤其他外部接口方法。
①自定义View的属性:创建res/values/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="firstColor" format="color" />
<attr name="circleWidth" format="dimension" />
<attr name="speed" format="integer" />
<declare-styleable name="CustomProgressBar">
<attr name="firstColor" />
<attr name="circleWidth" />
<attr name="speed" />
</declare-styleable>
</resources>
②在View的构造方法中构造我们的自定义View
public class PercentProgressBar extends View {③重新onMeasure():(本自定义View未处理)。
private final String TAG = "PercentProgressBar";
//画笔
private Paint mPaint;
//动画速度
private int mSpeed;
//圆环宽度
private int mCircleWidth;
//默认基体颜色
private int mFirstColor;
//进度
private int mProgress;
//各部分所占角度
private int[] percents;
//各部分的颜色
private int[] colors;
//判断是否开始动画
private boolean start = false;
public PercentProgressBar(Context context) {
this(context, null);
}
public PercentProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PercentProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
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_circleWidth:
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();
colors = new int[]{Color.YELLOW, Color.GREEN, Color.BLUE};
}
...
}
④重写onDraw()
@Override
protected void onDraw(Canvas canvas) {
int center = getWidth()/2;
int radius = center - mCircleWidth/2;
mPaint.setStrokeWidth(mCircleWidth);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);
mPaint.setColor(mFirstColor);
canvas.drawCircle(center, center, radius, mPaint);
if(!start) return;
if(mProgress < percents[0]){
mPaint.setColor(colors[0]);
canvas.drawArc(oval, 0, mProgress, false, mPaint);
}else if(mProgress < percents[1]+percents[0]){
mPaint.setColor(colors[0]);
canvas.drawArc(oval, 0, percents[0], false, mPaint);
mPaint.setColor(colors[1]);
canvas.drawArc(oval, percents[0], mProgress-percents[0], false, mPaint);
}else {
mPaint.setColor(colors[0]);
canvas.drawArc(oval, 0, percents[0], false, mPaint);
mPaint.setColor(colors[1]);
canvas.drawArc(oval, percents[0], percents[1], false, mPaint);
mPaint.setColor(colors[2]);
canvas.drawArc(oval, percents[0]+percents[1], mProgress-percents[1]-percents[0], false, mPaint);
}
}
⑤接口方法:
/**
* 开始各部分百分比绘画
*/
public void start(){
start = true;
new Thread(){
@Override
public void run() {
mProgress = 0;
while (mProgress <=360 ){
mProgress++;
postInvalidate();
try {
this.sleep(mSpeed);
}catch (Exception e){
e.printStackTrace();
}
}
}
}.start();
}
/**
* @param values 设置各部分的值
*/
public void setPercent(float[] values){
float sum = 0f;
for(float value : values){
sum += value;
}
percents = new int[values.length];
for(int i=0; i<values.length; i++){
percents[i] = (int) (values[i]/sum*360);
}
Log.i(TAG, percents[0]+","+percents[1] +","+ percents[2]);
}
/**
* @param colors 设置自定义各部分颜色
*/
public void setDifColor(int[] colors){
this.colors = colors;
Log.i(TAG, colors[0]+","+colors[1] +","+ colors[2]);
}
在Activity中使用(布局文件比较简单,就不贴了):
mPercentProgressBar = (PercentProgressBar)findViewById(R.id.progress_bar);
mPercentProgressBar.setPercent(new float[]{120, 56, 180});
mPercentProgressBar.setDifColor(new int[]{0xffff0000, 0xff00ff00,0xff0000ff});mPercentProgressBar.start();