自定义钟表

自定义钟表,分为几个步骤

  1. 绘制原盘
  2. 绘制刻度(大刻度、小刻度…)
  3. 绘制指针(时针、分针、秒针)
  4. 让指针根据当前时间动起来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package com.utstartcom.custom.view.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import java.util.Calendar;
/**
* Created by JesseHev on 2017/9/28.
*/
public class ClockView extends View {
Paint mPaint, mTextPaint;
int mWidth, mHeight, mRadius = 200;
//表盘圆心坐标
int centerX, centerY;
//刻度到圆圈之间的距离
int scalePadding = 10;
public ClockView(Context context) {
super(context);
init();
}
public ClockView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setTextSize(30);
mTextPaint.setColor(Color.BLACK);
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();
mHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
centerX = mWidth / 2;
centerY = mHeight / 2;
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawChicle(canvas);
drawCale(canvas);
drawPointer(canvas);
//每1000ms刷新一次UI
postInvalidateDelayed(1000);
}
/**
* 绘制指针
*/
private void drawPointer(Canvas canvas) {
//获取当前时间,然后根据当前时间计算指针旋转角度绘制指针
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
canvas.save();
//计算时针小时数旋转角度 =360/12*小时数(当前小时数+分钟数+秒数 这才是真正的小时数,分数同理)
float hourDegrees = 30 * (hour + minute / 60f + second / 60f / 60f);
canvas.rotate(hourDegrees, centerX, centerY);
canvas.drawLine(centerX, centerY - centerX * 0.5f, centerX, centerY + centerX * 0.15f, mPaint);
canvas.restore();
mPaint.setStrokeWidth(8);
canvas.save();
//计算分针分数旋转角度
float minuteDegrees = 360 / 60 * (minute + second / 60f);
canvas.rotate(minuteDegrees, centerX, centerY);
canvas.drawLine(centerX, centerY - centerX * 0.5f, centerX, centerY + centerX * 0.15f, mPaint);
canvas.restore();
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(7);
canvas.save();
//计算秒针秒旋转角度
float secondDegrees = 6 * second;
canvas.rotate(secondDegrees, centerX, centerY);
canvas.drawLine(centerX, centerY - mRadius + scalePadding, mWidth / 2,
mHeight / 2 + mWidth / 2f * 0.15f, mPaint);
canvas.restore();
canvas.drawCircle(centerX, centerY, 10, mPaint);
}
/**
* 绘制刻度
*/
private void drawCale(Canvas canvas) {
for (int i = 0; i < 60; i++) {
if (i == 0 || i == 15 || i == 30 || i == 45) {//大刻度 分别对应 12点、3点、6点、9点
mPaint.setStrokeWidth(6);
mPaint.setColor(Color.BLACK);
canvas.drawLine(centerX, centerY - mRadius + scalePadding, centerX,
centerY - mRadius + scalePadding + 30, mPaint);
String text = String.valueOf(i == 0 ? 12 : i / 5);
//设置字体中心到屏幕左边的距离
mTextPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, centerX, centerY - mRadius + scalePadding + 60, mTextPaint);
} else if (i == 5 | i == 10 //中刻度 分别对应1点、2点、4点、5点、7点、8点、10点、11点
|| i == 20 || i == 25 || i == 35 || i == 40 || i == 50 || i == 55) {
mPaint.setStrokeWidth(4);
mPaint.setColor(Color.RED);
String text = String.valueOf(i / 5);
canvas.drawText(text, centerX, centerY - mRadius + scalePadding + 60, mTextPaint);
canvas.drawLine(centerX, centerY - mRadius + scalePadding, centerX,
centerY - mRadius + scalePadding + 20, mPaint);
} else {//小刻度 对应每秒的刻度
mPaint.setStrokeWidth(2);
mPaint.setColor(Color.RED);
String text = String.valueOf(i);
canvas.drawLine(centerX, centerY - mRadius + scalePadding, centerX,
centerY - mRadius + scalePadding + 10, mPaint);
}
//每次绘制一个刻度都将canvas选择6°,注:每个刻度为 = 360/60
canvas.rotate(6, mWidth / 2, mHeight / 2);
}
}
/**
* 绘制表盘
*/
private void drawChicle(Canvas canvas) {
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(centerX, centerY, mRadius, mPaint);
}
}

在xml中引用

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.utstartcom.custom.view.view.ClockView
android:padding="5dp"
android:layout_width="300dp"
android:layout_height="300dp"
/>
</LinearLayout>