Android自定义控件,每秒自动动态更新时间

By admin in 4858美高梅 on 2019年5月5日

    使用canvas绘制石英钟

 下文是有的代码,完整代码参照:https://github.com/lemoncool/canvas-clock,可一贯下载。

 首先看一下意义图:每隔一秒会动态更新时间

  4858美高梅 1

 1、早先时期计划

  一.
HTML中妄图二个容器存放画布,并为其设置width,height。

<div>
    <canvas id="clock" height="200px" width="200px"></canvas>
</div>

  2.在js中赢得canvas画布成分,并获取其上下文,对应的不二等秘书诀是 Android自定义控件,每秒自动动态更新时间。canvas.getContext

let dom = document.getElementById('clock');   //获取画布
let ctx = dom.getContext('2d');               //获取canvas上下文 
let width = ctx.canvas.width;                 //获取预先设置的canvas画布宽度
let height = ctx.canvas.height;               //获取预先设置的canvas画布高度
let r = width / 2;                 //定义半径,为后续绘制圆形图案做准备

2、绘制圆盘背景:

function drawBackground() {
    ctx.save();                               //每次开始前都要保存当前画布状态,以免移动画布影响后续绘制
    ctx.translate(r, r);                      //将起始点位置移动至圆心
    ctx.beginPath();                          //每次开始绘制前必须开始一条路径
    ctx.lineWidth = 10 ;                      //设置绘制线的宽度
    ctx.arc(0, 0, r - ctx.lineWidth / 2, 0, 2 * Math.PI, false);    //画一个整圆
    ctx.stroke();                             //对圆进行描边
}

 三、绘制时辰刻度(壹-1二)及分钟刻度(每一种小时之内的小圆点
标志分钟)

  
绘制前,首先看一下每一种时辰刻度(一,2,三,…1贰)在所在容器的坐标显著

       
 4858美高梅 24858美高梅 3

       
 4858美高梅 4

所以,每一刻度点的  X = r*cos(角度)====>X = Math.cos(rad) * r
                 Y = r*sin(角度)====>Y = Math.sin(rad) * r  

但是 Math.cos(rad)与 Math.sin(rad) 中的角度都要求是弧度,弧度与角度的转换见上图,即圆周360度 = 弧度 2*Math.PI 

所以,时钟一圈共有12个小时,那个每小时所占的弧度为:rad = 2 * Math.PI / 12
     时钟一圈共有60的分钟,那么每分钟所占的弧度为:rad = 2 * Math.PI / 60

 那么,清楚了小时和分钟的弧度总括,我们开头绘制吧

var hourNumbers = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];    //定义标记小时的数组
    hourNumbers.map(function (number, i) {                    //遍历 取出各刻度及所在索引
 //每个刻度所占弧度为索引乘以一小时的弧度,即 1点钟30度,2点钟60度,以此类推..
    var rad = 2 * Math.PI / 12 * i;           
    var x = Math.cos(rad) * (r - 30 * rem); 
    var y = Math.sin(rad) * (r - 30 * rem);         //确定各刻度点 X、Y坐标 
    ctx.textAlign = 'center';                 //绘制的刻度在整个画布左右居中 
    ctx.textBaseline = 'middle';               //同理,上下居中 
    ctx.font = 18 * rem + "px Arial";            //设置显示刻度的数字 1,2,3.. 的字体及字号 
    ctx.fillText(number, x, y)                //绘制文字
});

  绘制标识分钟的小圆点 道理
与绘图小时相似,只是弧度为60等分,绘制成实心的小圆点

  绘制后的效应图如下:

  4858美高梅 5

四、绘制时针、分针、秒针及圆心点

  绘制时针与分针原理为 绘制直线

      首要运用的秘技为:ctx.rotate(
);  ctx.moveTo();
 ctx.lineTo();
 ctx.lineCap= ”
“;

      以下以绘制时针为例陈述原理:

function drawHour(hour, minute) {
    ctx.save();                                    //存储画布状态,前面提到过
    ctx.beginPath();                               //开始一条路径
    var rad = 2 * Math.PI / 12 * hour;             //每小时旋转的弧度
    var mrad = 2 * Math.PI / 12 / 60 * minute;     //每分钟旋转的弧度
    ctx.rotate(rad + mrad);                        //旋转
    ctx.lineWidth = 6;                           //设置宽度
    ctx.moveTo(0, 10);                            //移动起始点至(0,10)                       
    ctx.lineTo(0, -r / 2);                        //从起始点绘制到(0,r/2)点,负号表示方向向上
    ctx.lineCap = 'round';                        //设置结束线帽
    ctx.stroke();                                 //描边
    ctx.restore();                                //将画布恢复到旋转之前状态
}

  时针、分针、秒针、原点绘制后效果图如下:

  4858美高梅 6

伍、使机械钟指针动起来

     原理为获取当前时刻 new
Date()
,设置电磁料理计时器 setInterval(draw,
1000) 
每隔1段时间更新绘制画布

function draw() {
    ctx.clearRect(0, 0, width, height);                //重新绘制之前清除画布,否则状态叠加,页面显示如下图
    var now = new Date();                              //获取当前时间
    var hour = now.getHours();                         //当前小时
    var minute = now.getMinutes();                     //当前分钟
    var second = now.getSeconds();                     //当前秒数
    drawBackground();                                  //绘制圆盘背景
    drawHour(hour, minute);                            //绘制时针
    drawMinute(minute);                                //绘制分针
    drawSecond(second);                                //绘制秒针
    drawDot();                                         //绘制原点
    ctx.restore();                                     //回复画布状态
}
setInterval(draw, 1000);                               //定时器执行整个绘画方法

4858美高梅 7

上图为没有撤废画布ctx.clearRect()的功能,所以切记
一定要在绘制在此以前清除画布,重新画。

6、挂钟出现了,且会自定更新。

4858美高梅 8

  整个代码逻辑参照了慕课网中 Silva
Zhou 
先生的教学,再次对先生表示感激。

     
 小说为温馨记录总结,方便日后选取。假使发掘难题,迎接留言指引~ 

 

利用canvas绘制动态时钟–每秒自动动态更新时间,canvas更新时间

上边是种类在手提式有线电话机上运转的成效图

HTML5使用之挂钟,html伍时钟

行使HTML5的Canvas
API可以产生大家以前意料之外的动画效果,从前我们想在网页上放置1个石英钟,须求先用flash工具创立三个石英钟,并写上复杂的JavaScript代码,然后载入到页面中。而HTML伍的赶到,大家能够直接在页面中选择canvas标签并协作javascript就足以达成1个不错的时钟。

4858美高梅 9

前几天,大家共同来使用HTML伍构建一个指针会走动的电子钟表。

HTML

咱俩只须求在html中放置四个canvas标签:#clock,宽度和可观都以400px。

[html] view plaincopy  

  1. <!DOCTYPE HTML>  
  2. <html>  
  3. <head>  
  4. <meta charset=”utf-8″>  
  5. <title>HTML伍接纳之石英钟</title>  
  6. </head>  
  7.   
  8. <body>  
  9. <canvas id=”clock” width=”400″ height=”400″></canvas>   
  10. </body>  
  11. </html>  

Javascript

大家先来得到当前岁月:包涵时分秒,确认保障在张开页面时能稳固指针地点,并且定义好圆点坐标和分钟角度变量。

[js] view plaincopy  

  1. var time = new Date();  
  2. var h = time.getHours(); //时  
  3. var m = time.getMinutes(); //分  
  4. var s = time.getSeconds(); //秒  
  5. h=h>12?(h-12)*5+parseInt(m/12):h*5+parseInt(m/1二); //时针 初步地点  
  6. var x=200,y=200,sAngle=0; //x y 原点 秒针角度变量  

接下去,大家采纳canvas来绘制石英钟,大家写一个函数draw(),绘制刻度,施行该函数三遍,则秒针顺时针走动陆分一0个圆弧度。

第二,获取canvas绘图对象,绘制挂钟刻度。大家将机械钟(圆)划分为十三个刻度,即每一个刻度代表三个钟头,当然,你也得以划分为伍十八个刻度,那样各类刻度就代表壹分钟。

[js] view plaincopy  

  1. function draw(){  
  2.     var c=document.getElementById(“clock”);  
  3.     var ctx=c.getContext(“二d”); //获取绘图对象  
  4.     ctx.clearRect(0,0,c.width,c.height); //清除上次绘制的图样  
  5.     s++;//秒针  
  6.    
  7.     ctx.fillStyle = ‘#fff’ //填充森林绿背景象   
  8.     ctx.fillRect(0,0,c.width,c.height);   //设置画布区域  
  9.    
  10.     ctx.save(); //保存当前绘制状态  
  11.    
  12.     // 时间刻度  
  13.     for(var i=0;i<12;i++){ //划分12刻度  
  14.         var angle=(Math.PI*贰)/12; //得到各样刻度对应的弧度  
  15.         ctx.beginPath();//初步绘制  
  16.         ctx.font=”1二px Arial”; //设置字体  
  17.         if(i==0||i==3||i==6||i==9){ //当指向0(12点)、3点、6点、9点时  
  18.              ctx.fillStyle=”red”; //刻度为法国红  
  19.              radius=4; //刻度半径长四px  
  20.         }else{  
  21.              ctx.fillStyle=”blue”; //刻度为莲红  
  22.              radius=三; //刻度半径长为3px  
  23.         }  
  24.    
  25.         ctx.arc(x,y-100,radius,0,Math.PI*二,true); //画圆作为刻度  
  26.         ctx.fill(); //填充路线  
  27.         transform(ctx,x,y,angle,true);  //刻度分布                
  28.     }  
  29.     ctx.restore(); //苏醒上次保留的绘图状态  
  30.     …  
  31. }  

遵照上面的代码能够绘制一个带刻度的圆盘作为机械钟的表面。接下来大家继续在函数draw()里写时分秒指针的团团转。

[js] view plaincopy  

  1. function draw(){  
  2.     …  
  3.     sAngle=(Math.PI*2)/60*s; //秒度  
  4.     //时针转动  
  5.     ctx.save();   
  6.     ctx.strokeStyle=”red”;  
  7.     ctx.lineWidth=3;  
  8.     transform(ctx,x,y,(Math.PI*2)/60*h);   
  9.     sj(ctx,x,y,y-40);  
  10.     ctx.restore();  
  11.       
  12.     //分针转动  
  13.     ctx.save();  
  14.     ctx.strokeStyle=”blue”;  
  15.     ctx.lineWidth=2;  
  16.     transform(ctx,x,y,(Math.PI*2)/60*m);   
  17.     sj(ctx,x,y,y-68);  
  18.     ctx.restore();  
  19.    
  20.     //秒针转动  
  21.     ctx.save();  
  22.     ctx.strokeStyle=”#000″;  
  23.     transform(ctx,x,y,sAngle);    
  24.     sj(ctx,x,y,y-80);  
  25.     ctx.restore();  
  26.       
  27.     //数据整理  
  28.     if(s%60==0){  
  29.         sAngle=0,s=0,m++;  
  30.         if(m%1贰==0){ //每11分 时针旋转一次  
  31.             if(m!=0)h++;  
  32.             if(m%60==0)m=0;  
  33.         }  
  34.         if(h%60==0)h=0;   
  35.     }  
  36. }  

每调用3回draw(),大家对时分秒针设置差异的填充颜色和指针粗细,绘制指针,依照弧度转动指针地点,在那之中大家调用了自定义函数trans()和pointer()。

函数pointer()用来绘制指针。其中ctx表示canvas对象,x,y是圆点坐标,z是指针头的职分。

[js] view plaincopy  

  1. function pointer(ctx,x,y,z){  
  2.      ctx.beginPath();  
  3.      ctx.moveTo(x,y);  
  4.      ctx.lineTo(x,z);  
  5.      ctx.stroke();  
  6.      ctx.fill();  
  7. }  

函数transform()用来旋转指针。当中ctx表示canvas对象,x,y是圆点坐标,angle是转动角度。

[js] view plaincopy  

  1. function trans(ctx,x,y,angle){  
  2.      ctx.transform(Math.cos(angle), Math.sin(angle),   
  3.         -Math.sin(angle), Math.cos(angle),   
  4.         x*(1-Math.cos(angle)) + x*Math.sin(angle),   
  5.         y*(1-Math.cos(angle)) – y*Math.sin(angle))  
  6. }  

提起底,我们设置每隔1分钟(即一千皮秒)实践二次draw()。

[js] view plaincopy  

  1. setInterval(“draw()”,1000);  

利用 HTML5 的Canvas
API能够做到大家在此之前意料之外的动画片效果,此前笔者们想在网页上放置3个挂钟,要求先用flash工…

    使用canvas绘制石英钟

 下文是一对代码,完整代码参照:,可径直下载。

 首先看一下功用图:每隔一秒会动态更新时间

  4858美高梅 10

 1、前期计划

  一. HTML中希图二个容器存放画布,并为其安装width,height。

<div>
    <canvas id="clock" height="200px" width="200px"></canvas>
</div>

  二.在js中获取canvas画布成分,并获取其上下文,对应的点子是 canvas.getContext

let dom = document.getElementById('clock');   //获取画布
let ctx = dom.getContext('2d');               //获取canvas上下文 
let width = ctx.canvas.width;                 //获取预先设置的canvas画布宽度
let height = ctx.canvas.height;               //获取预先设置的canvas画布高度
let r = width / 2;                 //定义半径,为后续绘制圆形图案做准备

2、绘制圆盘背景:

function drawBackground() {
    ctx.save();                               //每次开始前都要保存当前画布状态,以免移动画布影响后续绘制
    ctx.translate(r, r);                      //将起始点位置移动至圆心
    ctx.beginPath();                          //每次开始绘制前必须开始一条路径
    ctx.lineWidth = 10 ;                      //设置绘制线的宽度
    ctx.arc(0, 0, r - ctx.lineWidth / 2, 0, 2 * Math.PI, false);    //画一个整圆
    ctx.stroke();                             //对圆进行描边
}

 3、绘制小时刻度(1-12)及分钟刻度(各样小时之内的小圆点 标识分钟)

  
绘制前,首先看一下种种小时刻度(壹,贰,三,…1二)在所在容器的坐标明确

       
 4858美高梅 114858美高梅 12

       
 4858美高梅 13

所以,每一刻度点的  X = r*cos(角度)====>X = Math.cos(rad) * r
                 Y = r*sin(角度)====>Y = Math.sin(rad) * r  

但是 Math.cos(rad)与 Math.sin(rad) 中的角度都要求是弧度,弧度与角度的转换见上图,即圆周360度 = 弧度 2*Math.PI 

所以,时钟一圈共有12个小时,那个每小时所占的弧度为:rad = 2 * Math.PI / 12
     时钟一圈共有60的分钟,那么每分钟所占的弧度为:rad = 2 * Math.PI / 60

 那么,清楚了小时和分钟的弧度总计,我们起先绘制吧

var hourNumbers = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];    //定义标记小时的数组
    hourNumbers.map(function (number, i) {                    //遍历 取出各刻度及所在索引
 //每个刻度所占弧度为索引乘以一小时的弧度,即 1点钟30度,2点钟60度,以此类推..
    var rad = 2 * Math.PI / 12 * i;           
    var x = Math.cos(rad) * (r - 30 * rem); 
    var y = Math.sin(rad) * (r - 30 * rem);         //确定各刻度点 X、Y坐标 
    ctx.textAlign = 'center';                 //绘制的刻度在整个画布左右居中 
    ctx.textBaseline = 'middle';               //同理,上下居中 
    ctx.font = 18 * rem + "px Arial";            //设置显示刻度的数字 1,2,3.. 的字体及字号 
    ctx.fillText(number, x, y)                //绘制文字
});

  绘制标识分钟的小圆点 道理
与绘图时辰相似,只是弧度为60等分,绘制成实心的小圆点

  绘制后的效益图如下:

  4858美高梅 14

4、绘制时针、分针、秒针及圆心点

  绘制时针与分针原理为 绘制直线

      重要使用的格局为:ctx.rotate( );  ctx.moveTo();
 ctx.lineTo(); ctx.lineCap= ” “*
;*

      以下以绘制时针为例陈述原理:

function drawHour(hour, minute) {
    ctx.save();                                    //存储画布状态,前面提到过
    ctx.beginPath();                               //开始一条路径
    var rad = 2 * Math.PI / 12 * hour;             //每小时旋转的弧度
    var mrad = 2 * Math.PI / 12 / 60 * minute;     //每分钟旋转的弧度
    ctx.rotate(rad + mrad);                        //旋转
    ctx.lineWidth = 6;                           //设置宽度
    ctx.moveTo(0, 10);                            //移动起始点至(0,10)                       
    ctx.lineTo(0, -r / 2);                        //从起始点绘制到(0,r/2)点,负号表示方向向上
    ctx.lineCap = 'round';                        //设置结束线帽
    ctx.stroke();                                 //描边
    ctx.restore();                                //将画布恢复到旋转之前状态
}

  时针、分针、秒针、原点绘制后效果图如下:

  4858美高梅 15

伍、使机械钟指针动起来

     原理为获取当前岁月 new Date(),设置放大计时器 setInterval(draw,
1000) 
每隔一段时间更新绘制画布

function draw() {
    ctx.clearRect(0, 0, width, height);                //重新绘制之前清除画布,否则状态叠加,页面显示如下图
    var now = new Date();                              //获取当前时间
    var hour = now.getHours();                         //当前小时
    var minute = now.getMinutes();                     //当前分钟
    var second = now.getSeconds();                     //当前秒数
    drawBackground();                                  //绘制圆盘背景
    drawHour(hour, minute);                            //绘制时针
    drawMinute(minute);                                //绘制分针
    drawSecond(second);                                //绘制秒针
    drawDot();                                         //绘制原点
    ctx.restore();                                     //回复画布状态
}
setInterval(draw, 1000);                               //定时器执行整个绘画方法

4858美高梅 16

上海教室为未有排除画布ctx.clearRect()的职能,所以切记
一定要在绘制此前清除画布,重新画。

陆、时钟出现了,且会自定更新。

4858美高梅 17

  整个代码逻辑参照了慕课网中 Silva
Zhou 
先生的讲课,再一次对教师职员和工人表示谢谢。

       作品为和煦记录总括,方便日后采用。倘诺开掘难点,迎接留言辅导~ 

 

使用canvas绘制机械钟 下文是壹对代码,完整代码参照:

GIF演示图

4858美高梅 18

效果图

体制效果演示图

4858美高梅 19

效果图

4858美高梅 20

效果图

4858美高梅 21

效果图

贯彻原理分析

  • 刻度线绘制:画1个刻度线很轻巧,就是canvas.drawLine,不过依靠角度每30度制图二个刻度线怎么落到实处呢,大家1开首想到的或是会是基于角度,利用三角函数等去计算各样刻度线的发端坐标和终止坐标,但这种艺术未免过于复杂,稍有不慎就能计算错误。可是使用画布的旋转canvas.rotate就能丰富的简要,刻度线只需依照1二点钟趋向绘制就能够,每一回绘制完七个刻度线,画布旋转30度,再依照1二点钟势头绘制就能够。
  • 指南针绘制:一样也是因此canvas.drawLine绘制3个指针,为paint设置不一样的习性落成时针,分针,秒针的显得样式,同理,若是我们遵照角度去计算指针的坐标,那就很复杂,这里也是由此画布的团团转,那么旋转的角度怎么规定呢,就是依附当前时刻去分明(具体算法前面代码中具体分析)。
  • 动态:为了兑现石英钟的动态转动,我们必要在onDraw中每1分钟获取三遍当今日子,然后计算3个指针的旋转角度,再绘制就行了。

这么壹剖析,其实自定义时钟很简短,就是绘制圆,然后通过画布的团团转绘制刻度线和指针。

切实落到实处进程

  1. 绘制圆

     //绘制圆
     canvas.drawCircle(centerX, centerY, radius, circlePaint);
    

    其中centerX和centerY为圆心,用当下控件的中央点就能够,radius为圆的半径,选取当下控件宽高的最小值/二就能够,或然电动安装。

  2. 制图刻度线

    4858美高梅 ,11个刻度线,循环11回,每一种刻度线正是一小时的刻度线,能够设置不一致的体制区分。然后依据1二点钟势头绘制刻度线。

    开始x坐标:圆心x坐标;

    开始y坐标:圆心y坐标-半径+间隙;

    结束x坐标:圆心x坐标;

    甘休y坐标:开头y坐标+刻度线长度;

    每绘制完一个刻度线后,画布就在事先的底子上旋转30度,继续绘制1二点钟刻度线,那样,刻度线就凭仗旋转后的画布绘制,也正是斜着绘制了刻度线,很有益于的兑现了刻度线的绘图。

    此处给出首要的绘图代码,全体代码前边贴出

     //刻度线长度
     private final static int MARK_LENGTH = 20;
    
     //刻度线与圆的间隙
     private final static int MARK_GAP = 12;
    
     //绘制刻度线
     for (int i = 0; i < 12; i++) {
         if (i % 3 == 0) {//一刻钟
             markPaint.setColor(mQuarterMarkColor);
         } else {
             markPaint.setColor(mMinuteMarkColor);
         }
         canvas.drawLine(
                 centerX,
                 centerY - radius + MARK_GAP,
                 centerX,
                 centerY - radius + MARK_GAP + MARK_LENGTH,
                 markPaint);
         canvas.rotate(30, centerX, centerY);
     }
     canvas.save();
    
  3. 绘图指针

    绘图时针,分针,秒针,大家分别用一个canvas去绘制,最终再将那三个画布的bitmap绘制到控件的canvas中,为的是单独主宰每一种画布的转动角度。

    首先分析时针的指针角度,钟一圈是十一个钟头,360度,那么每小时正是30度,若是当前岁月的钟点是h(1二小时制),那么时针的旋转角度正是h*30,同刻度线同等,我们也不去总计该角度的指针的各样坐标,而是平素将时针的画布旋转h*30度,然后绘制1二点钟来头的时针就行了。

    随后是分针角度,钟一圈是60分钟,360度,那么每秒钟正是6度,假若当前时刻的分钟是m,那么分针的团团转角度就是m*6

    最后是秒针角度,钟1圈是60秒,360度,那么每秒正是陆度,假若当前时刻的秒数是s,那么秒针的团团转角度正是s*6

    剖析完了时针,分针,秒针的角度获取,那么以往就很简单了,在onDraw中,大家每过1秒获取三次当前时光的时分秒,遵照地点的算法计算角度,然后旋转相应的画布,之后绘制相应的指针(当然要注意画布的清空和死灰复燃),那么四个乘胜时间的流逝而旋转的石英钟就出来了。

    那边给出绘制时针的重中之重代码,其余几个指针是近似的,具体代码后边贴出

     @Override
     protected void onDraw(Canvas canvas) {
         Calendar calendar = Calendar.getInstance();
         int hour12 = calendar.get(Calendar.HOUR);
         int minute = calendar.get(Calendar.MINUTE);
         int second = calendar.get(Calendar.SECOND);
    
         //保存画布状态
         hourCanvas.save();
         //清空画布
         hourCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
         //旋转画布
         hourCanvas.rotate(hour12 * 30, centerX, centerY);
         //绘制12点钟方向的时针
         hourCanvas.drawLine(centerX, centerY,
                 centerX, centerY - hourLineLength, hourPaint);
         //重置画布状态,即撤销之前旋转的角度,回到未旋转之前的状态
         hourCanvas.restore();
    
         canvas.drawBitmap(hourBitmap, 0, 0, null); 
    
         //每隔1s重新绘制
         postInvalidateDelayed(1000);
     }
    

    而是大家会意识有几许一点都不大的供应满足不了须求,秒针是会一秒一秒的转,不过时针和分针总是在整数地方,当过了60秒,分针才会跳到下1分钟,当过了60分钟,时针才会跳到下叁个时辰,大家日常看的石英钟都是随着秒针的转动,分针和时针都以有必然的偏移量的,当然我们的石英钟也要那样光彩夺目,那么什么样总计呢?

    时针:前面说过,每时猪时针旋转30度,要是当前光阴的钟点是h(1二时辰制),那么时针的转动角度就是h*30。那么每分钟时针旋转多少度呢,答案是30/60=0.5度(每时辰60分钟,每小时30度),所以时针的偏移量就是m*0.伍,那么只要当前的时光是一:30,那么时针旋转的角度正是一*30+30*0.5,就是四伍度,改成变量公式就是h*30+m*0.伍,那么修改下方面包车型客车代码

     hourCanvas.rotate(hour12 * 30 + minute * 0.5f, centerX, centerY);
    

    分针:借使当前时光的分钟是m,那么分针的团团转角度便是m*陆,每秒钟分针旋转6/60(每分钟60秒,每分钟陆度),所以分针的偏移量是s*0.一,那么分针画布旋转的的代码正是

     minuteCanvas.rotate(minute * 6 + second * 0.1f, centerX, centerY);
    

    秒针:秒针就依照每分钟陆度旋转

     secondCanvas.rotate(second * 6, centerX, centerY);
    

总结

经过地方的2个步骤,我们就绘制出了2个会慢慢移动的电子钟了。

1体化的代码和连串大家能够到笔者的github中查看,里面有相关的使用方法,同时那么些类型上传到了maven货仓,能够经过gradle直接选取

compile 'com.don:clockviewlibrary:1.0.1'

github地址:https://github.com/zhijieeeeee/ClockView

完整代码

public class ClockView extends View {

    //使用wrap_content时默认的尺寸
    private final static int DEFAULT_SIZE = 400;

    //刻度线宽度
    private final static int MARK_WIDTH = 8;

    //刻度线长度
    private final static int MARK_LENGTH = 20;

    //刻度线与圆的距离
    private final static int MARK_GAP = 12;

    //时针宽度
    private final static int HOUR_LINE_WIDTH = 10;

    //分针宽度
    private final static int MINUTE_LINE_WIDTH = 6;

    //秒针宽度
    private final static int SECOND_LINE_WIDTH = 4;

    //圆心坐标
    private int centerX;
    private int centerY;

    //圆半径
    private int radius;

    //圆的画笔
    private Paint circlePaint;

    //刻度线画笔
    private Paint markPaint;

    //时针画笔
    private Paint hourPaint;

    //分针画笔
    private Paint minutePaint;

    //秒针画笔
    private Paint secondPaint;

    //时针长度
    private int hourLineLength;

    //分针长度
    private int minuteLineLength;

    //秒针长度
    private int secondLineLength;

    private Bitmap hourBitmap;
    private Bitmap minuteBitmap;
    private Bitmap secondBitmap;

    private Canvas hourCanvas;
    private Canvas minuteCanvas;
    private Canvas secondCanvas;

    //圆的颜色
    private int mCircleColor = Color.WHITE;
    //时针的颜色
    private int mHourColor = Color.BLACK;
    //分针的颜色
    private int mMinuteColor = Color.BLACK;
    //秒针的颜色
    private int mSecondColor = Color.RED;
    //一刻钟刻度线的颜色
    private int mQuarterMarkColor = Color.parseColor("#B5B5B5");
    //分钟刻度线的颜色
    private int mMinuteMarkColor = Color.parseColor("#EBEBEB");
    //是否绘制3个指针的圆心
    private boolean isDrawCenterCircle = false;

    //获取时间监听
    private OnCurrentTimeListener onCurrentTimeListener;

    public void setOnCurrentTimeListener(OnCurrentTimeListener onCurrentTimeListener) {
        this.onCurrentTimeListener = onCurrentTimeListener;
    }

    public ClockView(Context context) {
        super(context);
        init();
    }

    public ClockView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ClockView);
        mCircleColor = a.getColor(R.styleable.ClockView_circle_color, Color.WHITE);
        mHourColor = a.getColor(R.styleable.ClockView_hour_color, Color.BLACK);
        mMinuteColor = a.getColor(R.styleable.ClockView_minute_color, Color.BLACK);
        mSecondColor = a.getColor(R.styleable.ClockView_second_color, Color.RED);
        mQuarterMarkColor = a.getColor(R.styleable.ClockView_quarter_mark_color, Color.parseColor("#B5B5B5"));
        mMinuteMarkColor = a.getColor(R.styleable.ClockView_minute_mark_color, Color.parseColor("#EBEBEB"));
        isDrawCenterCircle = a.getBoolean(R.styleable.ClockView_draw_center_circle, false);
        a.recycle();
        init();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        reMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        centerX = width / 2 ;
        centerY = height / 2;
        radius = Math.min(width, height) / 2;

        hourLineLength = radius / 2;
        minuteLineLength = radius * 3 / 4;
        secondLineLength = radius * 3 / 4;

        //时针
        hourBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        hourCanvas = new Canvas(hourBitmap);

        //分针
        minuteBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        minuteCanvas = new Canvas(minuteBitmap);

        //秒针
        secondBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        secondCanvas = new Canvas(secondBitmap);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制圆
        canvas.drawCircle(centerX, centerY, radius, circlePaint);
        //绘制刻度线
        for (int i = 0; i < 12; i++) {
            if (i % 3 == 0) {//一刻钟
                markPaint.setColor(mQuarterMarkColor);
            } else {
                markPaint.setColor(mMinuteMarkColor);
            }
            canvas.drawLine(
                    centerX,
                    centerY - radius + MARK_GAP,
                    centerX,
                    centerY - radius + MARK_GAP + MARK_LENGTH,
                    markPaint);
            canvas.rotate(30, centerX, centerY);
        }
        canvas.save();

        Calendar calendar = Calendar.getInstance();
        int hour12 = calendar.get(Calendar.HOUR);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);

        //(方案一)每过一小时(3600秒)时针添加30度,所以每秒时针添加(1/120)度
        //(方案二)每过一小时(60分钟)时针添加30度,所以每分钟时针添加(1/2)度
        hourCanvas.save();
        //清空画布
        hourCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        hourCanvas.rotate(hour12 * 30 + minute * 0.5f, centerX, centerY);
        hourCanvas.drawLine(centerX, centerY,
                centerX, centerY - hourLineLength, hourPaint);
        if (isDrawCenterCircle)//根据指针的颜色绘制圆心
            hourCanvas.drawCircle(centerX, centerY, 2 * HOUR_LINE_WIDTH, hourPaint);
        hourCanvas.restore();

        //每过一分钟(60秒)分针添加6度,所以每秒分针添加(1/10)度;当minute加1时,正好second是0
        minuteCanvas.save();
        //清空画布
        minuteCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        minuteCanvas.rotate(minute * 6 + second * 0.1f, centerX, centerY);
        minuteCanvas.drawLine(centerX, centerY,
                centerX, centerY - minuteLineLength, minutePaint);
        if (isDrawCenterCircle)//根据指针的颜色绘制圆心
            minuteCanvas.drawCircle(centerX, centerY, 2 * MINUTE_LINE_WIDTH, minutePaint);
        minuteCanvas.restore();

        //每过一秒旋转6度
        secondCanvas.save();
        //清空画布
        secondCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        secondCanvas.rotate(second * 6, centerX, centerY);
        secondCanvas.drawLine(centerX, centerY,
                centerX, centerY - secondLineLength, secondPaint);
        if (isDrawCenterCircle)//根据指针的颜色绘制圆心
            secondCanvas.drawCircle(centerX, centerY, 2 * SECOND_LINE_WIDTH, secondPaint);
        secondCanvas.restore();

        canvas.drawBitmap(hourBitmap, 0, 0, null);
        canvas.drawBitmap(minuteBitmap, 0, 0, null);
        canvas.drawBitmap(secondBitmap, 0, 0, null);

        //每隔1s重新绘制
        postInvalidateDelayed(1000);

        if (onCurrentTimeListener != null) {
            //小时采用24小时制返回
            int h = calendar.get(Calendar.HOUR_OF_DAY);
            String currentTime = intAdd0(h) + ":" + intAdd0(minute) + ":" + intAdd0(second);
            onCurrentTimeListener.currentTime(currentTime);
        }
    }

    /**
     * 初始化
     */
    private void init() {
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setStyle(Paint.Style.FILL);
        circlePaint.setColor(mCircleColor);

        markPaint = new Paint();
        circlePaint.setAntiAlias(true);
        markPaint.setStyle(Paint.Style.FILL);
        markPaint.setStrokeCap(Paint.Cap.ROUND);
        markPaint.setStrokeWidth(MARK_WIDTH);

        hourPaint = new Paint();
        hourPaint.setAntiAlias(true);
        hourPaint.setColor(mHourColor);
        hourPaint.setStyle(Paint.Style.FILL);
        hourPaint.setStrokeCap(Paint.Cap.ROUND);
        hourPaint.setStrokeWidth(HOUR_LINE_WIDTH);

        minutePaint = new Paint();
        minutePaint.setAntiAlias(true);
        minutePaint.setColor(mMinuteColor);
        minutePaint.setStyle(Paint.Style.FILL);
        minutePaint.setStrokeCap(Paint.Cap.ROUND);
        minutePaint.setStrokeWidth(MINUTE_LINE_WIDTH);

        secondPaint = new Paint();
        secondPaint.setAntiAlias(true);
        secondPaint.setColor(mSecondColor);
        secondPaint.setStyle(Paint.Style.FILL);
        secondPaint.setStrokeCap(Paint.Cap.ROUND);
        secondPaint.setStrokeWidth(SECOND_LINE_WIDTH);

    }

    /**
     * 重新设置view尺寸
     */
    private void reMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
        int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
        int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (measureWidthMode == MeasureSpec.AT_MOST
                && measureHeightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(DEFAULT_SIZE, DEFAULT_SIZE);
        } else if (measureWidthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(DEFAULT_SIZE, measureHeight);
        } else if (measureHeightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(measureWidth, DEFAULT_SIZE);
        }
    }

    public interface OnCurrentTimeListener {
        void currentTime(String time);
    }

    /**
     * int小于10的添加0
     *
     * @param i
     * @return
     */
    private String intAdd0(int i) {
        DecimalFormat df = new DecimalFormat("00");
        if (i < 10) {
            return df.format(i);
        } else {
            return i + "";
        }
    }
}

自定义属性

<declare-styleable name="ClockView">
    <attr name="circle_color" format="color" />
    <attr name="hour_color" format="color" />
    <attr name="minute_color" format="color" />
    <attr name="second_color" format="color" />
    <attr name="quarter_mark_color" format="color" />
    <attr name="minute_mark_color" format="color" />
    <attr name="draw_center_circle" format="boolean" />
</declare-styleable>

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有