安卓自定义View实现钟表
转载请注明出处:http://blog.csdn.net/baiyuliang2013/article/details/45535227
之前实现过html5版的钟表,html5也有一个画板属性Canvas,相对于安卓的Canvas来说html5的功能要强大的多,就拿钟表的实现,html5要方便简单的多,而安卓实现起来则非常复杂,像指针转动,html5可以画一条线,然后可以用这条线旋转一个弧度即可,而安卓必须是已知起点坐标和终点坐标,这就需要精确计算起始坐标了。先看下效果图,因为是图静态的,动态图也懒得做,所以看个大致效果即可,具体效果可以下载demo观看:
这个钟表并不算完美,正常的钟表,秒针每转动一格,分针和时针都会跟着转动相应的弧度,但本例中偷了个懒,只有秒针转一周时,分针才移动一小格,分针转一周时,时针移动一大格,不满一周的情况下不动,因为画线需要精确的坐标值,如果做到这种效果那工作量可就大了去了,因此我们知道原理即可。
实现思路:
1.重写View,并在ondraw方法中绘图;
2.定义边框宽度,刻度宽度,长度,指针宽度,长度,计算圆心坐标及表盘半径;
3.绘制边框:
mPaint.setStrokeWidth(bordWidth); // 设置圆环的宽度
mPaint.setColor(bordColor);
canvas.drawCircle(getWidth()/2, getWidth()/2, r, mPaint);
4.绘制刻度:
//画刻度
//12
mPaint.setStrokeWidth(timeLineB_W);
mPaint.setColor(timeColor);
canvas.drawLine(circleX,bordWidth, circleX, bordWidth+timeLineB_H, mPaint);
//12-1
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(90-i*6)) ),(float)(circleX-r*Math.cos(Math.toRadians(i*6))), (float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-i*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(i*6))),mPaint);
}
//1
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(60)) ),(float)(circleX-r*Math.cos(Math.toRadians(30))), (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60))),(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30))),mPaint);
//1-2
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(90-30-i*6)) ),(float)(circleX-r*Math.cos(Math.toRadians(30+i*6))), (float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-i*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(30+i*6))),mPaint);
}
//2
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(30)) ),(float)(circleX-r*Math.cos(Math.toRadians(60))), (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30))),(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60))),mPaint);
//2-3
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(90-60-i*6)) ),(float)(circleX-r*Math.cos(Math.toRadians(60+i*6))), (float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-i*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(60+i*6))),mPaint);
}
//3
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine(getWidth()-bordWidth, circleX, getWidth()-bordWidth-timeLineB_H, circleX, mPaint);
//3-4
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(i*6)) ),(float)(circleX+r*Math.cos(Math.toRadians(90-i*6))), (float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(i*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-i*6))),mPaint);
}
//4
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(30)) ),(float)(circleX+r*Math.cos(Math.toRadians(60))), (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30))),(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60))),mPaint);
//4-5
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(30+i*6)) ),(float)(circleX+r*Math.cos(Math.toRadians(90-30-i*6))), (float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(30+i*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-i*6))),mPaint);
}
//5
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(60)) ),(float)(circleX+r*Math.cos(Math.toRadians(30))), (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60))),(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30))),mPaint);
//5-6
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX+r*Math.cos(Math.toRadians(60+i*6)) ),(float)(circleX+r*Math.cos(Math.toRadians(90-60-i*6))), (float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(60+i*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-i*6))),mPaint);
}
//6
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine(circleX,getWidth()-bordWidth, circleX, getWidth()-bordWidth-timeLineB_H,mPaint);
//6-7
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(90-i*6)) ),(float)(circleX+r*Math.cos(Math.toRadians(i*6))), (float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-i*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(i*6))),mPaint);
}
//7
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(60)) ),(float)(circleX+r*Math.cos(Math.toRadians(30))), (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60))),(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30))),mPaint);
//7-8
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(90-30-i*6)) ),(float)(circleX+r*Math.cos(Math.toRadians(30+i*6))), (float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-i*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(30+i*6))),mPaint);
}
//8
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(30)) ),(float)(circleX+r*Math.cos(Math.toRadians(60))), (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30))),(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60))),mPaint);
//8-9
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(90-60-i*6)) ),(float)(circleX+r*Math.cos(Math.toRadians(60+i*6))), (float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-i*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(60+i*6))),mPaint);
}
//9
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine(bordWidth,circleX, bordWidth+timeLineB_H, circleX,mPaint);
//9-10
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(i*6)) ),(float)(circleX-r*Math.cos(Math.toRadians(90-i*6))), (float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(i*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-i*6))),mPaint);
}
//10
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(30)) ),(float)(circleX-r*Math.cos(Math.toRadians(60))), (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30))),(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60))),mPaint);
//10-11
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(30+i*6)) ),(float)(circleX-r*Math.cos(Math.toRadians(90-30-i*6))), (float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(30+i*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-i*6))),mPaint);
}
//11
mPaint.setStrokeWidth(timeLineB_W);
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(60)) ),(float)(circleX-r*Math.cos(Math.toRadians(30))), (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60))),(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30))),mPaint);
//11-12
mPaint.setStrokeWidth(timeLineS_W);
for(int i=1;i<6;i++){
canvas.drawLine((float)(circleX-r*Math.cos(Math.toRadians(60+i*6)) ),(float)(circleX-r*Math.cos(Math.toRadians(90-60-i*6))), (float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(60+i*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-i*6))),mPaint);
}
刻度是逐一计算起始点坐标并绘制的,拿1点的刻度来说,
已知圆心坐标(x,y),半径r,AB长度为a,求A点B点坐标。这应该是初中的题目了吧,很好计算,只要求出A点到y轴和x轴的距离,B点到y轴和x轴的距离即可(最方便的办法就是利用正余玄函数了,而Java也提供了正余玄函数的算法:Math.cos(Math.toRadians(角度值),因为Math.cos传的是弧度,所以要将角度转化为弧度如Math.toRadians(60)),当然要注意屏幕坐标与数学中的象限坐标是不同的,所以AB点坐标要用求出的距离值结合圆的半径求出该点在屏幕中的实际坐标,然后画线即可。
5.绘制指针交点:
mPaint.setStrokeWidth(2); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(circleX,circleX, 10, mPaint);
6.秒针转动:
到这里,我们得思考下,钟表是要动的啊,那怎么实现打开应用钟表就开始走呢?很简单吧,初始化View时,在View的构造方法中开启个线程去不断重绘View即可,时间间隔当然为一秒,这也就给你视觉感是指针一秒转动一次,另外需要你对秒针分针时针转动时相互关联所走的角度有一个清晰的思路,如果你连他们之间的关系都搞不明白,那看代码就更不用说了:
while (true){
if (ss == 360){
mm++;//秒针每转一圈,分针走一格,一格6度,一圈60格
if(mm==60){
hh++;//分针转一圈,时针走一格,一格30度,一圈12格
if(hh==12){
hh=0;
}
mm=0;
}
ss = 0;
}
postInvalidate(); //重绘
try{
Thread.sleep(1000); //暂停1秒
} catch (InterruptedException e){
e.printStackTrace();
}
ss+=6; //360度,分针每秒转动6度
}
秒针转动:
mPaint.setStrokeWidth(timeLineS_W-5);//设置秒针宽度
mPaint.setColor(pointColor);
r=r-timeLineB_H-5;//设置秒针长度
//分针随秒针转动
if(ss<=30){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-ss*1))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(ss*1))), mPaint);
}else if(ss<=60){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(ss-30)*1))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(30+(ss-30)*1))), mPaint);
}else if(ss<=90){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(ss-60)*1))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(60+(ss-60)*1))), mPaint);
}else if(ss<=120){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians((ss-90)*1))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-(ss-90)*1))), mPaint);
}else if(ss<=150){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(30+(ss-120)*1))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(ss-120)*1))), mPaint);
}else if(ss<=180){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(60+(ss-150)*1))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(ss-150)*1))), mPaint);
}else if(ss<=210){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-(ss-180)*1))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians((ss-180)*1))), mPaint);
}else if(ss<=240){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(ss-210)*1))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(30+(ss-210)*1))), mPaint);
}else if(ss<=270){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(ss-240)*1))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(60+(ss-240)*1))), mPaint);
}else if(ss<=300){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians((ss-270)*1))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-(ss-270)*1))),mPaint);
}else if(ss<=330){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(30+(ss-300)*1))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(ss-300)*1))),mPaint);
}else if(ss<=360){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(60+(ss-330)*1))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(ss-330)*1))),mPaint);
}
7.分针转动:
mPaint.setStrokeWidth(timeLineS_W);//设置分针宽度
r=circleX-bordWidth;//还原
r=r-timeLineB_H-50;//设置分针长度
//分针随秒针转动
if(mm<=5){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-mm*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(mm*6))), mPaint);
}else if(mm<=10){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(mm-5)*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(30+(mm-5)*6))), mPaint);
}else if(mm<=15){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(mm-10)*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(60+(mm-10)*6))), mPaint);
}else if(mm<=20){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians((mm-15)*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-(mm-15)*6))), mPaint);
}else if(mm<=25){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(30+(mm-20)*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(mm-20)*6))), mPaint);
}else if(mm<=30){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(60+(mm-25)*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(mm-25)*6))), mPaint);
}else if(mm<=35){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-(mm-30)*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians((mm-30)*6))), mPaint);
}else if(mm<=40){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(mm-35)*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(30+(mm-35)*6))), mPaint);
}else if(mm<=45){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-60-(mm-40)*6))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(60+(mm-40)*6))), mPaint);
}else if(mm<=50){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians((mm-45)*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-(mm-45)*6))),mPaint);
}else if(mm<=55){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(30+(mm-50)*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(mm-50)*6))),mPaint);
}else if(mm<=60){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(60+(mm-55)*6))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-30-(mm-55)*6))),mPaint);
}
8.时针转动:
r=circleX-bordWidth;//还原
r=r-timeLineB_H-120;//设置时针长度
//时针随分针转动
if(hh<=3){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-hh*30))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(hh*30))), mPaint);
}else if(hh<=6){
canvas.drawLine(circleX,circleX,(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians((hh-3)*30))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians(90-(hh-3)*30))), mPaint);
}else if(hh<=9){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-(hh-6)*30))),(float)(circleX+(r-timeLineS_H)*Math.cos(Math.toRadians((hh-6)*30))), mPaint);
}else if(hh<=12){
canvas.drawLine(circleX,circleX,(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians((hh-9)*30))),(float)(circleX-(r-timeLineS_H)*Math.cos(Math.toRadians(90-(hh-9)*30))),mPaint);
}
9.绘制刻度值:
//写时刻数字
mPaint.setTextSize(26);
mPaint.setStrokeWidth(2);
mPaint.setColor(bordColor);
canvas.drawText("12", circleX-timeLineB_W, bordWidth+timeLineB_H+30, mPaint);
canvas.drawText("1", (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60)))-20,(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30)))+20, mPaint);
canvas.drawText("2", (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30)))-20,(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60)))+20, mPaint);
canvas.drawText("3", getWidth()-bordWidth-timeLineB_H-20, circleX+10, mPaint);
canvas.drawText("4",(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30)))-20,(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60))), mPaint);
canvas.drawText("5", (float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60)))-15,(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30)))-5, mPaint);
canvas.drawText("6",circleX-10, getWidth()-bordWidth-timeLineB_H-10, mPaint);
canvas.drawText("7", (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60))),(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(30)))-10, mPaint);
canvas.drawText("8", (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30)))+10,(float)(circleX+(r-timeLineB_H)*Math.cos(Math.toRadians(60)))+5, mPaint);
canvas.drawText("9", bordWidth+timeLineB_H+10, circleX+10, mPaint);
canvas.drawText("10", (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30)))+10,(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60)))+20, mPaint);
canvas.drawText("11", (float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(60))),(float)(circleX-(r-timeLineB_H)*Math.cos(Math.toRadians(30)))+25, mPaint);
在做的过程中会发现规律,就是每个大刻度(30度)即12点-1点,1点-2点......这之间所用的代码是相同的,只需要改变一下转动的角度值即可。秒针分为360,一次+6,转动一格为6度;分针分为60,在秒针到360时+1,转动一格为6度;时针分为12,在分针到60时+1,转动一格为30度;这也就是计算的时候有*1的,有*6的,有*30的原因,具体可以体会下代码中的算法,或者你有更好的算法欢迎分享出来!
demo下载地址:http://download.csdn.net/detail/baiyuliang2013/8668103
安卓自定义View实现钟表的更多相关文章
- 安卓自定义View教程目录
基础篇 安卓自定义View基础 - 坐标系 安卓自定义View基础 - 角度弧度 安卓自定义View基础 - 颜色 进阶篇 安卓自定义View进阶 - 分类和流程 安卓自定义View进阶 - Canv ...
- 安卓自定义View进阶-Canvas之画布操作 转载
安卓自定义View进阶-Canvas之画布操作 转载 https://www.gcssloop.com/customview/Canvas_Convert 本来想把画布操作放到后面部分的,但是发现很多 ...
- android自定义View之钟表诞生记
很多筒子觉得自定义View是高手的象征,其实不然.大家觉得自定义View难很多情况下可能是因为自定义View涉及到了太多的类和API,把人搞得晕乎乎的,那么今天我们就从最简单的绘图API开始,带大家来 ...
- 安卓自定义View(一)自定义控件属性
自定义View增加属性第一步:定义属性资源文件 在/res/values 文件夹下建立"Values XML layout",按照如下定义一个textview的属性 <?xm ...
- 安卓自定义View实现图片上传进度显示(仿QQ)
首先看下我们想要实现的效果如下图(qq聊天中发送图片时的效果): 再看下图我们实现的效果: 实现原理很简单,首先我们上传图片时需要一个进度值progress,这个不管是自己写的上传的方法还是使用第三方 ...
- 安卓自定义View实例-----跟随手指移动的鸟
今天学习了一些安卓开发中的自定义布局,编写了简单一个实例,“跟随手指移动的鸟”,需要两张图片,背景图片和鸟的图片,鸟的图片可以在屏幕中跟随手指的移动而移动. 1.将两张图片导入到mipmap中: 2. ...
- 安卓自定义View基础 --坐标系,角度弧度,颜色
转自:https://www.gcssloop.com/customview/CustomViewIndex/ 1.坐标系 2.角度弧度 3.颜色 一.屏幕坐标系和数学坐标系的区别 由于移动设备一般定 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- Android自定义View之ProgressBar出场记
关于自定义View,我们前面已经有三篇文章在介绍了,如果筒子们还没阅读,建议先看一下,分别是android自定义View之钟表诞生记.android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检 ...
随机推荐
- permu(变态考试题)
题目描述 给定一个严格递增的序列T,求有多少个T的排列S满足:∑min(T[i],S[i])=k 输入输出格式 输入格式: 第一行两个数n,k 第二行n个数,表示T 输出格式: 一个正整数表示答案,答 ...
- ●UVA 11796 Dog Distance
题链: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- hihocoder——1041国庆出游(搜索)
描述 小Hi和小Ho准备国庆期间去A国旅游.A国的城际交通比较有特色:它共有n座城市(编号1-n):城市之间恰好有n-1条公路相连,形成一个树形公路网.小Hi计划从A国首都(1号城市)出发,自驾遍历所 ...
- poj 2888 Magic Bracelet(Polya+矩阵快速幂)
Magic Bracelet Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 4990 Accepted: 1610 D ...
- HDU 5506(GT and set)
题意: 表示看了很久,然而发现还是没看懂题. 正解:给你a个集合,让你把他们合并成k个,当两个集合有公共数字时可以合并. (一直以为是合并后,每个集合至少有两个数字相同- -,这英语也是醉了) 思路: ...
- TensorFlow-Bitcoin-Robot:Tensorflow 比特币交易机器人
简介 一个比特币交易机器人基于 Tensorflow LSTM 模型,仅供娱乐. A Bitcoin trade robot based on Tensorflow LSTM model.Just f ...
- Mybatis Generator 代码生成配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...
- Redis持久化的两种方式(RDB和AOF)
redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File). RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储 ...
- font-spider利器对webfont网页字体压缩使用
http://font-spider.org/ npm install font-spider -g hyheilizhitij(汉仪黑荔枝体简) //引入 @font-face{ font-fami ...
- python 类属性.方法 实例的基本用法
class man(): classify = "people"# 全局属性 def __init__(self,name,age,value,):#类方法 self.name = ...