The renderings are as follows:

Drawing process:

  • Draw the dial
  • Draw the calibration
  • Drawing Numbers
  • Rotation number
  • Draw time minute second pointer
  • Periodically refresh the pointer using Handler

Step by step:

  • Draw the dial

canvas.drawCircle(mWidth / 2, mHeight / 2, mHeight / 2 - dp2px(borderPadding), mPaint);
Copy the code

  • Draw the calibration

        // Draw the scale, rotate it by a certain Angle each time, and then continue to draw
        for (int i = 0; i < 60; i++) {
            if (i % 5= =0) { / / large scale
                mPaint.setStrokeWidth(dp2px(3));
                canvas.drawLine(mWidth / 2, dp2px(borderPadding), mWidth / 2, dp2px(23), mPaint);
            } else { / / small scale
                mPaint.setStrokeWidth(dp2px(1));
                canvas.drawLine(mWidth / 2, dp2px(borderPadding), mWidth / 2, dp2px(20), mPaint);
            }
            // Draw a total of 60 scales, each rotation 360°/60
            canvas.rotate(360 / 60, mWidth / 2, mHeight / 2);
        }
Copy the code

  • Drawing Numbers

        // Draw the scale number
        for (int i = 0; i < 12; i++) {
            // Draw the number, 12 in total
            canvas.drawText(String.valueOf(i==0?"12":i), mWidth / 2, dp2px(textPadding), mPaint);
        }
Copy the code

  • Rotation number

Why do we rotate numbers here? Some of you may have noticed that the numbers rotate with the Angle, which is very unfriendly, so we need to get the numbers straight

        // Draw the scale number
        for (int i = 0; i < 12; i++) {
            // Save the current canvas state
            canvas.save();
            // The center point to be rotated is positioned on the number. The Angle of rotation depends on the current tilt of the number
            canvas.rotate(-360/12*i, mWidth / 2, dp2px(textPadding)- mPaint.measureText(String.valueOf(i==0?"12":i)) / 2);
            // Draw the number
            canvas.drawText(String.valueOf(i==0?"12":i), mWidth / 2, dp2px(textPadding), mPaint);
            // Restore the rotated canvas
            canvas.restore();
            // Rotate around the center of the dial to draw the next scale
            canvas.rotate(360 / 12, mWidth / 2, mHeight / 2);
        }
Copy the code

And as you can see, all the numbers on the scale are already positive

  • Draw time minute second pointer

        // Draw the second hand
        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();
        // Draw the minute hand
        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();
        // Draw the hour hand
        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();
        // Draw the center dot
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(mWidth / 2, mHeight / 2, dp2px(5), mPaint);
Copy the code

  • Periodically refresh the pointer using Handler

When drawing the time/second pointer above, we have already added to the code logic to draw different angles based on time. Here, we just need to retrieve the system time every second and call invalidate() to redraw the interface, and the clock will “move”

    private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                mCalendar = Calendar.getInstance();
                // Redraw the page
                invalidate();
                // Refresh the page again after 1000ms
                sendEmptyMessageDelayed(0.1000); }};Copy the code
        // Get the current time
        int second = mCalendar.get(Calendar.SECOND);
        int hour = mCalendar.get(Calendar.HOUR);
        intminute = mCalendar.get(Calendar.MINUTE); .// Draw the time minute second pointer.Copy the code

  • Scan codes to experience Demo

  • Welcome to star

The source code has been uploaded to Github: github.com/lvkaixuan/C…

CSDN blog: blog.csdn.net/lvkaixuan/a…