有时间学习还要有时间总结,感觉学习真是痛苦,痛不欲生、痛苦并快乐着,学会了如果不记下来那么最后的结果就是忘记了,啥也不记得了,以后忘了也没有个地方去查,所以现在我就要做这个工作。其实做表这个demo是17年的8月31号,本来我其实就想画了表盘呢(也是没啥志气),没想到花完感觉空落落的,光秃秃的也不好看,我就想找找看看大家大家的思路是啥,怎么能让那个秒针动弹,然后还真有很简单的方法 postInvalidateDelayed(1000)(我试过这个方法,写1也是1秒,还不知道原理)。如果解决了这个问题那么做一个钟表很简单的,大概思路是这样的:
1.先把画笔的中点移到屏幕中心,画圆,外边画一个方,然后白色的背景就是表盘了,画刻度
2.计算秒针、分针、时针的角度,这就完成了。
先上一个图吧
思路讲完了,现在就是coding了,顺便也说一下一些方法的用法
这就是第一步,把基本的表盘给花出来
private void drawCircle(Canvas canvas) {
r = (float) (Math.min(mWidth, mHeight)/2 *0.8);
canvas.translate(mWidth/2, mHeight /2);//移动画布中心点到屏幕中央
paint.setColor(getResources().getColor(R.color.brown));//设置画笔的颜色
canvas.drawRect(-r-20,-r-20,r+20,r+20,paint);//画一个正方形,就是外边褐色的框
paint.setColor(getResources().getColor(R.color.black));
paint.setStyle(Paint.Style.FILL);//设置画笔是实心的,画出表盘的圆来
paint.setColor(getResources().getColor(R.color.white));
canvas.drawCircle(0,0,r+5,paint);
paint.setStyle(Paint.Style.STROKE);//设置画笔为描边
paint.setColor(getResources().getColor(R.color.black));
paint.setStrokeWidth(1);
paint.setTextSize(15);
canvas.save();//保存画布
int lineWidth;
for (int i = 0; i < 60; i++) {//现在就是要画出表盘的那些个刻度
if (i % 5 == 0) {//是画整点的刻度的,比如12,1,2,3点
paint.setStrokeWidth(3);//设置一下画笔的宽度
lineWidth = 20;//设置整点刻度的线长度
String text = String.valueOf(12 - i/5);//计算当前要填写的数字
Rect textBound = new Rect();
paint.getTextBounds(text, 0, text.length(), textBound);
canvas.save();
paint.setStrokeWidth(2);
paint.setTextSize(25);
paint.setStyle(Paint.Style.FILL);
canvas.translate(0,10+lineWidth-r+(textBound.bottom - textBound.top));
canvas.rotate(6 * i);//做一下画布的旋转,这样数字的显示就是正常的哩
canvas.drawText(text, -(textBound.right - textBound.left) / 2,10, paint);
canvas.restore();
}else{//画每一分的小刻度的
paint.setStrokeWidth(1);
lineWidth = 10;
paint.setStrokeWidth(1);
}
canvas.drawLine(0,-r+10,0,10+lineWidth-r,paint);
canvas.rotate(-360/60);//画布逆时针赚
}
canvas.restore();
}
表盘花完了就是做最重要的一步了,就是让表动起来,怎么让表动,就是定时的刷新,怎么做定时刷新,其实定时刷新还挺多的用Timer+handler等等一些,现在我就用一个简单的postInvalidateDelayed()方法。
/**
* 表的指针
* @param canvas 第一版使用的是60分的,每一秒6度
*/
private void drawPointer(Canvas canvas){
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY); //时
int minute = calendar.get(Calendar.MINUTE); //分
int second = calendar.get(Calendar.SECOND); //秒
int angleHour = ((hour % 60) * 360 / 12); //时针转过的角度
int angleMinute = minute * 360 / 60; //分针转过的角度
int angleSecond = second * 360 / 60; //秒针转过的角度
paint.setStyle(Paint.Style.FILL);
canvas.save();//分针转动
paint.setColor(getResources().getColor(R.color.black));
canvas.rotate(angleMinute);//旋转画布 angleMinute的角度
RectF rectFMinute = new RectF(-4, -r*2/3, 4, 30);
canvas.drawRoundRect(rectFMinute, 10, 10, paint);
canvas.restore();
int hourMinute = angleMinute / (6 * 12);//时针转动
if (hourMinute > 0) {//主要实现让时针12分钟转动一格,
// 防止时针一小时转一大格不好看
canvas.save();
canvas.rotate(angleHour+hourMinute * 6);
RectF rectFHour1 = new RectF(-6, -r/2, 6, 30);
canvas.drawRoundRect(rectFHour1, 10, 10, paint);
canvas.restore();
}else{
canvas.save();
canvas.rotate(angleHour);
RectF rectFHour = new RectF(-6, -r/2, 6, 30);
canvas.drawRoundRect(rectFHour, 10, 10, paint);
canvas.restore();
}
canvas.save();//秒针转动
paint.setColor(getResources().getColor(R.color.red));
canvas.drawCircle(0,0,15,paint);
canvas.rotate(angleSecond);
RectF rectFSecond = new RectF(-3, -r+5, 3, 30);
canvas.drawRoundRect(rectFSecond, 10, 10, paint);
canvas.restore();
}
这个是我刚开始的写法,如果这么写就会有一个不好看的地方就是分针每次一小格,感觉太明显了,当然这个问题不是我发现的,是我女朋友说的:那个分针怎么那么转呀,一下跳那么大老远。没办法,女朋友都容忍不了说明是大问题,我就想要不和分针一样,然后就把一小格继续细分让分针实现成一分钟慢慢的调一格也就是6度,12秒钟调一度,5个12秒刚好事一格。
/**
* 表的指针
* @param canvas 第二版使用的是每一分下边再细分6度,这样就可以让指针变化的范围更小
*/
private void drawPointerSecond(Canvas canvas){
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY); //时
int minute = calendar.get(Calendar.MINUTE); //分
int second = calendar.get(Calendar.SECOND); //秒
int angleHour = ((hour % 60) * 360 / 12); //时针转过的角度
int angleMinute = minute * 360 / 60; //分针转过的角度
int angleSecond = second * 360 / 60; //秒针转过的角度
paint.setStyle(Paint.Style.FILL);
int minuteSecond = angleSecond/(6*10);
if (minuteSecond>0) {
canvas.save();//分针转动
paint.setColor(getResources().getColor(R.color.black));
canvas.rotate(angleMinute + minuteSecond);//旋转画布 angleMinute的角度
RectF rectFMinute = new RectF(-4, -r*2/3, 4, 30);
canvas.drawRoundRect(rectFMinute, 10, 10, paint);
canvas.restore();
}else{
canvas.save();//分针转动
paint.setColor(getResources().getColor(R.color.black));
canvas.rotate(angleMinute);//旋转画布 angleMinute的角度
RectF rectFMinute = new RectF(-4, -r*2/3, 4, 30);
canvas.drawRoundRect(rectFMinute, 10, 10, paint);
canvas.restore();
}
int hourMinute = angleMinute / (6 * 12);//时针转动
if (hourMinute > 0) {//主要实现让时针12分钟转动一格,
// 防止时针一小时转一大格不好看
canvas.save();
canvas.rotate(angleHour+hourMinute * 6);
RectF rectFHour1 = new RectF(-6, -r/2, 6, 30);
canvas.drawRoundRect(rectFHour1, 10, 10, paint);
canvas.restore();
}else{
canvas.save();
canvas.rotate(angleHour);
RectF rectFHour = new RectF(-6, -r/2, 6, 30);
canvas.drawRoundRect(rectFHour, 10, 10, paint);
canvas.restore();
}
canvas.save();//秒针转动
paint.setColor(getResources().getColor(R.color.red));
canvas.drawCircle(0,0,15,paint);
canvas.rotate(angleSecond);
RectF rectFSecond = new RectF(-3, -r+5, 3, 30);
canvas.drawRoundRect(rectFSecond, 10, 10, paint);
canvas.restore();
}