![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/37939fba1a864b209bd45d7792235b6e.png)
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Calendar;
public class Clock extends View {
private static final String TAG = "Clock";
private int width = dp2px(100);
private int outRadius;
private int innerRadius;
private int numberRadius;
private int hourLineLen;
private int minuteLineLen ;
private int secondLineLen;
private Paint hourPaint;
private Paint minutePaint;
private Paint secondPaint;
private Paint slimPaint;
private Paint boldPaint;
private Paint numberPaint;
private int hour;
private int minute;
private int second;
public Clock(Context context) {
super(context);
}
public Clock(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
initValue();
}
private boolean running=false;
void updateTime(){
new Thread(new Runnable() {
@Override
public void run() {
while (running) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Calendar calendar = Calendar.getInstance();
hour = calendar.get(Calendar.HOUR);
minute = calendar.get(Calendar.MINUTE);
second = calendar.get(Calendar.SECOND);
invalidate();
}
}
}).start();
}
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
if(visibility==View.VISIBLE){
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_TIME_TICK);
running=true;
updateTime();
}else{
running=false;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width=w;
initValue();
initPaint();
}
private void initValue() {
outRadius = width / 2;
innerRadius = (int) (width / 2 * 0.9);
numberRadius = (int) (width / 2 * 0.8);
hourLineLen = (int) (width / 2 * 0.4);
minuteLineLen = (int) (width / 2 * 0.6);
secondLineLen = (int) (width / 2 * 0.8);
}
public Clock(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
this.width = width;
}
setMeasuredDimension(this.width, this.width);
}
private void initPaint() {
slimPaint = new Paint();
slimPaint.setStrokeWidth((float) (width * 0.013));
slimPaint.setAntiAlias(true);
slimPaint.setColor(Color.BLACK);
boldPaint = new Paint();
boldPaint.setStrokeWidth((float) (width * 0.02));
slimPaint.setAntiAlias(true);
boldPaint.setColor(Color.RED);
hourPaint = new Paint();
hourPaint.setColor(Color.BLACK);
hourPaint.setAntiAlias(true);
hourPaint.setStrokeCap(Paint.Cap.ROUND);
minutePaint = new Paint();
minutePaint.setColor(Color.RED);
minutePaint.setAntiAlias(true);
minutePaint.setStrokeCap(Paint.Cap.ROUND);
secondPaint = new Paint();
secondPaint.setColor(Color.BLACK);
secondPaint.setAntiAlias(true);
secondPaint.setStrokeCap(Paint.Cap.ROUND);
numberPaint = new Paint();
numberPaint.setColor(Color.BLACK);
numberPaint.setTextSize((float) (width * 0.066));
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
drawScale(canvas);
Calendar calendar = Calendar.getInstance();
String time=calendar.get(Calendar.HOUR_OF_DAY)+":"+minute+":"+second;
float x= (float) getWidth() /2-numberPaint.measureText(time)/2;
float y= (float) (getHeight()/2+width*0.3);
canvas.drawText(time,x,y,numberPaint);
drawHour(canvas);
drawMinute(canvas);
drawSecond(canvas);
drawNumber(canvas);
}
private void drawNumber(Canvas canvas) {
float angle = 90;
int start = 12;
for (int i = 0; i < 12; i++) {
float x = (float) (width / 2 + Math.cos(Math.PI / 180 * angle) * numberRadius);
float y = (float) (width / 2 - Math.sin(Math.PI / 180 * angle) * numberRadius);
x -= numberPaint.measureText(String.valueOf(start)) / 2;
y += numberPaint.measureText(String.valueOf(start)) / 2;
canvas.drawText(String.valueOf(start), x, y, numberPaint);
start--;
angle += 30;
}
}
private void drawSecond(Canvas canvas) {
secondPaint.setColor(Color.GRAY);
canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, (float) (width * 0.0166), secondPaint);
int angele = 90 + (60 - second) * 6;
float startX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * (angele + 180)) * width * 0.083);
float startY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * (angele + 180)) * width * 0.083);
float endX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * angele) * secondLineLen);
float endY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * angele) * secondLineLen);
secondPaint.setStrokeWidth((float) (width * 0.0133));
canvas.drawLine(startX, startY, endX, endY, secondPaint);
}
private void drawHour(Canvas canvas) {
canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, (float) (width * 0.05), hourPaint);
int angele = 90 + (12 - hour) * 5 * 6;
float startX = (float) getWidth() / 2;
float startY = (float) getHeight() / 2;
float endX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * angele) * hourLineLen);
float endY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * angele) * hourLineLen);
hourPaint.setStrokeWidth((float) (width * 0.033));
canvas.drawLine(startX, startY, endX, endY, hourPaint);
}
private void drawMinute(Canvas canvas) {
canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, (float) (width * 0.033), minutePaint);
int angele = 90 + (60 - minute) * 6;
float startX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * (angele + 180)) * width * 0.066);
float startY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * (angele + 180)) * width * 0.066);
float endX = (float) (getWidth() / 2 + Math.cos(Math.PI / 180 * angele) * minuteLineLen);
float endY = (float) (getHeight() / 2 - Math.sin(Math.PI / 180 * angele) * minuteLineLen);
minutePaint.setStrokeWidth((float) (width * 0.0166));
canvas.drawLine(startX, startY, endX, endY, minutePaint);
}
private void drawScale(Canvas canvas) {
float angle = 90;
for (int i = 0; i < 60; i++) {
float startX = (float) (outRadius + Math.cos(Math.PI / 180 * angle) * outRadius);
float endX = (float) (outRadius + Math.cos(Math.PI / 180 * angle) * innerRadius);
float startY = (float) (outRadius - Math.sin(Math.PI / 180 * angle) * outRadius);
float endY = (float) (outRadius - Math.sin(Math.PI / 180 * angle) * innerRadius);
if (i % 5 == 0) {
canvas.drawLine(startX, startY, endX, endY, boldPaint);
} else {
canvas.drawLine(startX, startY, endX, endY, slimPaint);
}
angle += 6;
}
}
private int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());
}
}
<com.app.clock.Clock
android:layout_width="200dp"
android:layout_height="wrap_content"/>