Android自定義View之[能夠走動的時鐘]

效果圖以下:java

繪製流程:

  • 繪製錶盤
  • 繪製刻度
  • 繪製數字
  • 旋轉數字
  • 繪製時分秒指針
  • 使用Handler定時刷新指針

接下來一步一步實現:

  • 繪製錶盤

canvas.drawCircle(mWidth / 2, mHeight / 2, mHeight / 2 - dp2px(borderPadding), mPaint);
複製代碼
  • 繪製刻度

//繪製刻度,每次繪製完須要旋轉必定的角度,而後繼續繪製
        for (int i = 0; i < 60; i++) {
            if (i % 5 == 0) { //大刻度
                mPaint.setStrokeWidth(dp2px(3));
                canvas.drawLine(mWidth / 2, dp2px(borderPadding), mWidth / 2, dp2px(23), mPaint);
            } else { //小刻度
                mPaint.setStrokeWidth(dp2px(1));
                canvas.drawLine(mWidth / 2, dp2px(borderPadding), mWidth / 2, dp2px(20), mPaint);
            }
            //一共繪製60個刻度,每次旋轉360°/60
            canvas.rotate(360 / 60, mWidth / 2, mHeight / 2);
        }
複製代碼
  • 繪製數字

//繪製刻度數字
        for (int i = 0; i < 12; i++) {
            //繪製數字,一共12個
            canvas.drawText(String.valueOf(i==0?"12":i), mWidth / 2, dp2px(textPadding), mPaint);
        }
複製代碼
  • 旋轉數字

這裏爲何要旋轉數字呢?有人可能會注意到數字隨着角度旋轉了,這樣很不友好,因此咱們須要把數字都"正"過來 git

//繪製刻度數字
        for (int i = 0; i < 12; i++) {
            //保存當前畫布狀態
            canvas.save();
            //將要旋轉的中心點定位到數字上,旋轉的角度取決於當前數字傾斜的角度
            canvas.rotate(-360/12*i, mWidth / 2, dp2px(textPadding)- mPaint.measureText(String.valueOf(i==0?"12":i)) / 2);
            //繪製數字
            canvas.drawText(String.valueOf(i==0?"12":i), mWidth / 2, dp2px(textPadding), mPaint);
            //恢復被旋轉的畫布
            canvas.restore();
            //繞錶盤中心旋轉,繪製下一個刻度
            canvas.rotate(360 / 12, mWidth / 2, mHeight / 2);
        }
複製代碼

圖中能夠看到,刻度上的數字已經都"正"過來了

  • 繪製時分秒指針

//繪製秒針
        mPaint.setStrokeWidth(dp2px(1));
        mPaint.setColor(Color.BLACK);
        canvas.save();
        canvas.rotate(second * (365 / 60), mWidth / 2, mHeight / 2);
        canvas.drawLine(mWidth / 2, dp2px(textPadding) + dp2px(10), mWidth / 2, mHeight / 2 + dp2px(20), mPaint);
        canvas.restore();
        //繪製分針
        mPaint.setStrokeWidth(dp2px(3));
        mPaint.setColor(Color.BLACK);
        canvas.save();
        canvas.rotate((minute + (float) second / 60) * 360 / 60, mWidth / 2, mHeight / 2);
        canvas.drawLine(mWidth / 2, dp2px(textPadding) + dp2px(20), mWidth / 2, mHeight / 2 + dp2px(20), mPaint);
        canvas.restore();
        //繪製時針
        mPaint.setStrokeWidth(dp2px(5));
        mPaint.setColor(Color.BLACK);
        canvas.save();
        canvas.rotate((hour + (float) minute / 60) * 360 / 12, mWidth / 2, mHeight / 2);
        canvas.drawLine(mWidth / 2, dp2px(textPadding) + dp2px(50), mWidth / 2, mHeight / 2 + dp2px(20), mPaint);
        canvas.restore();
        //繪製中心圓點
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(mWidth / 2, mHeight / 2, dp2px(5), mPaint);
複製代碼
  • 使用Handler定時刷新指針

上面繪製時分秒指針的時候已經在代碼邏輯中加入根據時間來繪製不一樣的角度,這裏咱們只須要每隔一秒從新獲取一次系統時間,並調用invalidate()方法從新繪製界面,時鐘就能夠"動"起來了 github

private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                mCalendar = Calendar.getInstance();
                //從新繪製頁面
                invalidate();
                //1000ms後再刷新一次頁面
                sendEmptyMessageDelayed(0, 1000);
            }
        };
複製代碼
//獲取當前時間
        int second = mCalendar.get(Calendar.SECOND);
        int hour = mCalendar.get(Calendar.HOUR);
        int minute = mCalendar.get(Calendar.MINUTE);
        ...
        //繪製時分秒指針
        ...
複製代碼
  • 掃碼體驗Demo

  • 歡迎star

源碼已上傳到Github: github.com/lvkaixuan/C…canvas

CSDN博客地址: blog.csdn.net/lvkaixuan/a…ide

相關文章
相關標籤/搜索