模仿To_be_Designer的自定义时钟,主要是强化自己的技能,和写一点感悟
实现目标:
绘制直线:
在你要用这些变量前设置它的属性 这里设置了颜色,笔的宽度,样式(STROKE为空心) ,抗锯齿
mPaintLine =new Paint(); mPaintLine.setColor(Color.RED); mPaintLine.setStrokeWidth(10); mPaintLine.setStyle(Paint.Style.STROKE); mPaintLine.setAntiAlias(true);其它也是如此......
mPaintSecondLine =new Paint(mPaintLine); mPaintSecondLine.setStrokeWidth(7);
在测量方法里(onMeasure) 以前经常是
int widthMode = getMode(widthMeasureSpec)
int widthSIze = getMode(widthMeasureSpec)
if(widthMode==MeasureSpec.EXACTLY)
{
int result = widthSIze
}else
{
int result =getSuggestedMinimumWidth()
}
现在可以更简便的使用getDefaultSize()方法,这是android方便开发者做的优化,具体代码入下:
//就是封装了getMode和getsize width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(),widthMeasureSpec); setMeasuredDimension(width,height);
onDraw 有几点需要注意 save() 和restore()成对出现
再画时钟的刻度的时候
canvas.save(); //保存画布
canvas.rotate(360/12*i,width/2,height/2); //旋转画布
canvas.restore();//返回save的保存状态,这里就是变回未旋转的状态
//绘制分针 int minute = mCalendar.get(Calendar.MINUTE); //Calendar是掌管时间的类 , Calendar.getInstance();创建实例 float minuteDegree = minute/60f*360; // (360/60f)*minute,一个刻度占多少度*minute(0-60的取值范围) canvas.save(); canvas.rotate(minuteDegree,width/2,height/2); canvas.drawLine(width/2,height/2-90,width/2,height/2+20,mPaintLine); canvas.restore();
秒针同理
最难的时针,生活中时针会根据分针慢慢偏移角度,不能一下子从6点转到7点
float hourDegree = (hours*60+minute);//(12f*60)*360; 我算出来是(60*h+min)
暂时不想了
在这个时钟自定义类中我们定义了一个Handle ,Handle 有更新视图,处理消息的作用 ,invalidate()会调用onDraw(),这样就重绘了视图
//操作UI主线程 private Handler mHandle = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case NEED_INVALIDATE: //更新时间 mCalendar = Calendar.getInstance(); invalidate();//请求重新draw //延迟1500毫秒后发送空消息 sendEmptyMessageDelayed(NEED_INVALIDATE,1000);//这里不停的发送消息给handleMessage 就导致了不停的重绘 break; } } };
最后再有一个地方调用 ,触发这个handler
mHandler.sendEmptyMessageDelayed(MSG_PROGRESS_UPDATE, 100);
代码可以参考To_be_Designer 所以就不贴了 ,看To_be_Designer 和hongyang的博客能学到很多东西