public ProgressBarView(Context context, AttributeSet attrs) {
super(context,attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.progressbar);
paintBold = typedArray.getDimensionPixelSize(R.styleable.progressbar_paintBold,10);
linelengeth = typedArray.getDimensionPixelSize(R.styleable.progressbar_linelength,25);
linenumber = typedArray.getInteger(R.styleable.progressbar_linenumber,20);
backgroundColor = typedArray.getColor(R.styleable.progressbar_backgroundColor, Color.GRAY);
beforeColor = typedArray.getColor(R.styleable.progressbar_beforeColor,Color.YELLOW);
textColor = typedArray.getColor(R.styleable.progressbar_textColor,Color.BLACK);
max = typedArray.getInteger(R.styleable.progressbar_max,100);
//回收对象
typedArray.recycle();
}
backgroundPaint = new Paint();
backgroundPaint.setColor(backgroundColor);
backgroundPaint.setStrokeWidth(paintBold);
// 设置结合处样式,Round为圆弧,Miter为锐角,Bevel为直线
backgroundPaint.setStrokeJoin(Paint.Join.ROUND);
// 设置笔刷样式
backgroundPaint.setStrokeCap(Paint.Cap.ROUND);
// 抗锯齿
backgroundPaint.setAntiAlias(true);
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getSize(100,widthMeasureSpec);
height = getSize(100,heightMeasureSpec);
}
public int getSize(int defaultSize,int measureSpec){
int size = defaultSize;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode){
case MeasureSpec.UNSPECIFIED:
size = defaultSize;
break;
case MeasureSpec.AT_MOST:
size = specSize;
break;
case MeasureSpec.EXACTLY:
size = specSize;
break;
}
return size;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = width/2;
int y = height/2;
int r = x-5;
for (int i = 0;i<linenumber;i++){
canvas.drawLine(x,y-r,x,y-r+linelengeth,backgroundPaint);
canvas.rotate(360/linenumber,x,y);
}
int count = getProgress()*linenumber/max;
canvas.drawText(getProgress()*100/max+"%",x,y,textPaint);
for (;count>0;count--){
canvas.drawLine(x,y-r,x,y-r+linelengeth,beforePaint);
canvas.rotate(360/linenumber,x,y);
}
}
- 调用invalidate()或postInvalidateDelayed()进行页面重绘,重绘时只调用onDraw方法,postInvalidateDelayed()方法传入时间,即一定时间后重绘view。
- canvas的save和restore方法:
- save方法保存当前canvas的状态
- restore恢复save方法保存的状态,比如在canvas旋转之前调用save方法保存canvas状态,旋转后调用restore方法状态恢复到save方法保存的状态,即不用在反向旋转canvas,类似于图层的概念。save把画布状态放进状态栈中,restore返回栈中最顶层的状态栈画布。
- 当需要重绘的只是一个view里的一小部分,并不需要重绘其他部分,如钟表只用重绘指针并不用重绘表盘,可考虑建立两个view一个为表盘,一个是指针,然后用FrameLayout把两个view组合起来,重绘的时候只用重绘指针部分,个人觉得会提高性能。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = ClockView.getCirleX()/2;
int y = ClockView.getCirleY()/2;
int r= x-5;
initTime();
if (hour>12) hour = hour-12;
hourDegree = hour*30+minute/2;
minDegree = minute*6+second/10;
secDegree = second*6;
canvas.save();
canvas.rotate(secDegree,x,y);
canvas.drawLine(x,y-r+scalelength,x,y,secondPaint);
canvas.restore();
canvas.save();
canvas.rotate(minDegree,x,y);
canvas.drawLine(x,y-r+scalelength*4,x,y,minPaint);
canvas.restore();
canvas.rotate(hourDegree,x,y);
canvas.drawLine(x,y-r+scalelength*6,x,y,hourPaint);
postInvalidateDelayed(1000);
}
Demo地址https://github.com/liuchangjiang0119/CustomView