关于自定义view,学习了很长时间中午有进展了
首先自定义view分为两种:1:内部是空的进度条(如图1所示)2:内部是实心的进度条(图2);
首先说一下我的思路吧;
如果是空心的进度条,这就简单了,底部是一个圆形的实心图形1,然后在这个图形的基础上再画实心弧形2;
如果是实心的进度条,这相比于空心进度条就多了两步,也就是在弧形2之后再画一个实心圆3,最后放上text,也就是数字表示的进度条
首先看一下效果图吧。
先来讨论一下都要使用到哪些参数,首先图形1的roundRadius(圆的半径),roundColor(圆的颜色),
roundWidth(圆的宽度),图形2的roundProgressColor(圆的颜色)。text的textColor和textSize。
注意:圆1和圆2的半径是相同的,只有颜色不同;然后就是圆3的color和圆1的color是相同的;
private int roundRadius;//圆的半径
private int roundColor;//底层圆的color;
private int roundProgressColor;//上层圆的color;
private int roundWidth;//圆的宽度
private int textSize;//文字的大小
private int textColor;//文字的颜色
private int TYPE ;//是否是实心的
private float degress;//旋转的角度
private float intervalDegress;//每一次转动的角度
private String text; //字体(进度字体)
后面的TYPE ,是判断进度条的类型;degress是转动的总角度;intervalDegress是没刷新一次view要转动的角度;text也就是text进度条的内容了。
然后我们需要计算一下每一次刷新view所转动的角度也就是intervalDegress
/**
* 每一次转动的角度
* @param sumTime 转动360度所需要的总时间(单位:s)
* @param intervalTime 刷新view的时间间隔(单位:ms)
*/
public void setDegress(int sumTime, int intervalTime){
paint = new Paint();
rectF = new RectF();
intervalDegress = ((float)(360 * intervalTime)/((float)(sumTime * 1000)));
}
然后就是我们什么时候停止刷新view呢?也就是什么时候到达360度呢?
终止条件是:总角度大于360度的话,就终止刷新view
/**
* 判断如果度数大于360,就停止invalidate();
* @return ? true 停止 :false 继续
*/
public boolean getBooleanPaint(){
if(degress >= 360){
return true;
}else{
return false;
}
};
然后计算text的长度:
/*
* 计算 字体的长度
*/
public String getText() {
text = (int)(degress * 100/360) + "%";
return text;
}
然后就是每一次刷新view,也就是重新绘制view
/**
* 刷新view,也就是重新绘制view
*/
public void getPaint(){
invalidate();
}
好了准备工作做好了,现在我们需要写draw方法了;
代码示下:
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float width = getMeasuredWidth() / 2;
float height = getMeasuredHeight() / 2;
/**
* 画底层圆
*/
paint.setColor(roundColor);//设置底层颜色
paint.setAntiAlias(true);//设置无锯齿
paint.setStrokeWidth(roundWidth);//设置圆的宽度
paint.setStyle(Paint.Style.STROKE);//设置填充类型
rectF.left = width - roundRadius;
rectF.top = height - roundRadius;
rectF.right = width + roundRadius;
rectF.bottom = height + roundRadius;
canvas.drawOval(rectF, paint);
paint.setColor(roundProgressColor);
degress += intervalDegress;//计算总共总共转动的角度
rectF.left = width - roundRadius;
rectF.top = height - roundRadius;
rectF.right = width + roundRadius;
rectF.bottom = height + roundRadius;
if (TYPE == 1) {
//画实心的弧形
paint.setStyle(Paint.Style.FILL);
canvas.drawArc(rectF, -90, (int) degress, true, paint);
} else {
//空心的弧形
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(rectF, -90, (int) degress, true, paint);
//画内部圆
paint.setStyle(Paint.Style.FILL);
paint.setColor(roundColor);
rectF.left = width - roundRadius + roundWidth / 2;
rectF.top = height - roundRadius + roundWidth / 2;
rectF.right = width + roundRadius - roundWidth / 2;
rectF.bottom = height + roundRadius - roundWidth / 2;
canvas.drawOval(rectF, paint);
/**
* 放置文字
*/
paint.setTextSize(textSize);//设置字体的大小
paint.setColor(textColor);//设置字体的颜色
float measue = paint.measureText(getText());//计算字体的长度
canvas.drawText(getText(), width - measue/2,height, paint);
}
}
然后就是activity里的设置了
view = (MyViewGroup) findViewById(R.id.myviewgroup);
view.setRoundRadius(100);
view.setRoundColor(Color.GREEN);
view.setRoundProgressColor(Color.BLUE);
view.setTYPE(2);
view.setDegress(30,10);//总共30秒,每隔10毫秒刷新一次view
view.setRoundWidth(5);
view.setTextColor(Color.WHITE);
view.setTextSize(30);
view.getPaint();
最后创建一个定时器,在handler里面更新UI
TimerTask task = new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.arg1 = 1;
handler.sendMessage(msg);
}
};
timer = new Timer();
timer.schedule(task,0,10);//每隔10毫秒刷新一次view
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int arg = msg.arg1;
switch (arg){
case 1:{
/**
* 判断条件是否终止
*/
if(view.getBooleanPaint()){
timer.cancel();
}else{
view.getPaint();
}
break;
}
}
}
};
这样就行了Ok了,实际上我只是能写出来 但是写文章的话真的写不好,希望我写的这篇菜文能够帮到各位小伙伴