天天看點

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點刻度的角度,再畫刻度值即可。

Android自定義View---秒表/時鐘

總結

之前因為不想通過線程去控制秒表。是以,嘗試了一下繼承 Chronometer,但是由于其隻支援秒級,是以放棄了。時鐘/秒表在自定義view算比較好的練習,建議新上手的童鞋可以練練。

源碼下載下傳