Android自定义View---秒表/时钟

前言

网上看到一个html的秒表,赶脚不错,就闲着试试实现,时钟/秒表在学习自定义view中是一个不错的开始学习对象,毕竟看再多关于别人的自定义view文章也不如自己动动手。秒表

分析

画钟表,基本就是那么几个步骤,那先逐个分析一下:
- 画外表盘
- 画内表盘
- 画刻度线
- 画刻度值
- 提供外部接口(开始,暂停,复位等)

以上几步是必要的,当然顺序可以打乱,有的步骤也可以合并执行,视个人习惯而定。

核心代码

 protected void onDraw (Canvas canvas) {

    int width = getWidth();
    int height = getHeight();
    int cx = width/2;
    int cy = height/2;

    //draw out plate
    paint.setColor(plate_out_color);
    int out_radius = Math.min(cx, cy);
    canvas.drawCircle(cx, cy, out_radius, paint);

    //draw in plate
    paint.setColor(plate_in_color);
    int in_radius = out_radius-30;
    canvas.drawCircle(cx, cy, in_radius, paint);

    //draw scale
    paint.setColor(scale_color);
    for ( int i=0; i<120; i++)
    {
        if( i%5==0 ){//长线
            paint.setStrokeWidth(5);
            canvas.drawLine(width/2, height/2-in_radius+10, getWidth()/2, height/2-in_radius+5+25, paint);
            if( i%10==0 )
            {
                int value = (i/2);
                paint.setTextSize(25);
                String str =  (value==0)?"60":value+"";
                float x = width/2; //字体中心x
                float y = height/2-in_radius+5+25+40;
                int angle = -(360/120)*i;
                if ( angle!=0 ){
                    canvas.rotate(angle, x, y);//旋转画布,来实现字体的旋转
                }
                float len = paint.measureText(str);
                float sx = (getWidth()-len)/2; //字体起始位置x
                float sy = getHeight()/2-in_radius+5+25+50;
                canvas.drawText(str, sx, sy, paint);
                if (angle !=0 ){
                    canvas.rotate(-angle, x, y);
                }
            }
        }
        else {//短线
            paint.setStrokeWidth(2);                
            canvas.drawLine(width/2, height/2-in_radius+10, width/2, height/2-in_radius+5+18, paint);
        }
        canvas.rotate(360/120, width/2, height/2);//旋转画布
    }

    //draw pointer
    paint.setColor(pointer_color);
    float pointerValue = curValue%(60*1000);

    float roate = ((360f/120)/1000)*pointerValue ;
    canvas.rotate( roate,width/2, height/2);
    float pradius = (getHeight()/2+55)-(height/2-in_radius);
    RectF rectF = new RectF( width/2-pradius, height/2-in_radius-pradius , width/2+pradius, height/2-in_radius+pradius);
    canvas.drawArc( rectF,88, 4, true, paint);
    paint.setTextSize(5);
    canvas.drawCircle(cx, cy, 25, paint);
    paint.setColor(plate_in_color);
    canvas.drawCircle(cx, cy, 20, paint);

    canvas.rotate( 0-roate, width/2, height/2);
}  

上面画刻度时,遇到了2个值得思考的误区:

1、刻度线问题:本想通过不同角度来,表盘不动,画笔绕一圈画完刻度线,但赶脚不太好,后来看网上有哥们说,只需旋转表盘即可,这样我们只需要画正上方那个刻度线即可。

2、刻度值问题:刻度值画完后,表盘的字体是,慢慢倾斜的,这是因为我们画刻度线时,一起画了刻度值,而且以正上方为正面引起的,所以在画刻度值时,需以刻度值为中心旋转其相对12点刻度的角度,再画刻度值即可。

Alt text

总结

之前因为不想通过线程去控制秒表。所以,尝试了一下继承 Chronometer,但是由于其只支持秒级,所以放弃了。时钟/秒表在自定义view算比较好的练习,建议新上手的童鞋可以练练。

源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值