先上效果图:
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:background="#FFFFFF"
tools:context=".MainActivity">
<myapp.customview.CustomView.Clock
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
自定义View 文件:
public class Clock extends View {
int width = 800;
int height = 800;
public Clock(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.TRANSPARENT);
/*
绘制原盘
*/
Paint CircleBgPaint = new Paint();
CircleBgPaint.setColor(Color.WHITE);
CircleBgPaint.setStyle(Paint.Style.FILL);
CircleBgPaint.setAntiAlias(true);
int Radius = width / 2 - 60;
canvas.drawCircle(width /2 ,height / 2,Radius,CircleBgPaint);
/*
绘制原盘边框
*/
Paint CircleBgStrkoePaint = new Paint();
CircleBgStrkoePaint.setColor(Color.BLACK);
CircleBgStrkoePaint.setStrokeWidth(20);
CircleBgStrkoePaint.setStyle(Paint.Style.STROKE);
CircleBgStrkoePaint.setAntiAlias(true);
canvas.drawCircle(width /2 ,height / 2,Radius,CircleBgStrkoePaint);
/*
绘制刻度
分2个数组 因为drawLines 的大小限制
*/
Paint MarkPaint = new Paint();
MarkPaint.setColor(Color.BLACK);
MarkPaint.setStyle(Paint.Style.FILL);
MarkPaint.setAntiAlias(true);
MarkPaint.setStrokeWidth(20);
int R1 = Radius - 35;
int CenterX = width / 2;
int CenterY = height / 2;
float[] Marks = new float[7 * 4];
float[] Marks2 = new float[5 * 4];
for(int i = 0; i < 12;i++)
{
if(i <= 3) {
int degree = i * 30;
int x_s = (int) (Math.sin(Math.toRadians(degree)) * R1);
int y_s = (int) (Math.cos(Math.toRadians(degree)) * R1);
int x_e = (int) (Math.sin(Math.toRadians(degree)) * Radius);
int y_e = (int) (Math.cos(Math.toRadians(degree)) * Radius);
Marks[i * 4] = CenterX + x_s;
Marks[i * 4 + 1] = CenterY - y_s;
Marks[i * 4 + 2] = CenterX + x_e;
Marks[i * 4 + 3] = CenterY - y_e;
}
else if(i <= 6)
{
int degree = (i - 3) * 30;
int y_s = (int) (Math.sin(Math.toRadians(degree)) * R1);
int x_s = (int) (Math.cos(Math.toRadians(degree)) * R1);
int y_e = (int) (Math.sin(Math.toRadians(degree)) * Radius);
int x_e = (int) (Math.cos(Math.toRadians(degree)) * Radius);
Marks[i * 4] = CenterX + x_s;
Marks[i * 4 + 1] = CenterY + y_s;
Marks[i * 4 + 2] = CenterX + x_e;
Marks[i * 4 + 3] = CenterY + y_e;
}
else if(i <= 9)
{
int degree = (i - 6) * 30;
int x_s = (int) (Math.sin(Math.toRadians(degree)) * R1);
int y_s = (int) (Math.cos(Math.toRadians(degree)) * R1);
int x_e = (int) (Math.sin(Math.toRadians(degree)) * Radius);
int y_e = (int) (Math.cos(Math.toRadians(degree)) * Radius);
Marks2[( i - 7 ) * 4] = CenterX - x_s;
Marks2[( i - 7 ) * 4 + 1] = CenterY + y_s;
Marks2[( i - 7 ) * 4 + 2] = CenterX - x_e;
Marks2[( i - 7 ) * 4 + 3] = CenterY + y_e;
}
else if(i <= 11)
{
int degree = (i - 9) * 30;
int y_s = (int) (Math.sin(Math.toRadians(degree)) * R1);
int x_s = (int) (Math.cos(Math.toRadians(degree)) * R1);
int y_e = (int) (Math.sin(Math.toRadians(degree)) * Radius);
int x_e = (int) (Math.cos(Math.toRadians(degree)) * Radius);
Marks2[( i - 7 ) * 4] = CenterX - x_s;
Marks2[( i - 7 ) * 4 + 1] = CenterY - y_s;
Marks2[( i - 7 ) * 4 + 2] = CenterX - x_e;
Marks2[( i - 7 ) * 4 + 3] = CenterY - y_e;
}
}
canvas.drawLines(Marks,MarkPaint);
canvas.drawLines(Marks2,MarkPaint);
Paint TextPaint = new Paint();
TextPaint.setAntiAlias(true);
TextPaint.setTextAlign(Paint.Align.CENTER);
TextPaint.setTextSize(60);
TextPaint.setColor(Color.BLACK);
for(int i = 0 ;i < 12;i++)
{
int degree = i * 30;
int x_s = (int) (Math.sin(Math.toRadians(degree)) * ( R1 - 50 ));
int y_s = (int) (Math.cos(Math.toRadians(degree)) * ( R1 - 50 ));
String str = "";
if(i == 0)
{
str = "12";
}
else{
str = String.valueOf(i);
}
Paint.FontMetrics fm = TextPaint.getFontMetrics();
canvas.drawText(str,CenterX + x_s,CenterY - y_s + (fm.descent - fm.ascent) / 2 - fm.descent,TextPaint);
}
/*
获取当前时间
*/
long time = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");
String str = format.format(time);
String[] Hour_Min_Second = str.split("-");
Paint drawPaint = new Paint();
drawPaint.setColor(Color.BLACK);
drawPaint.setStyle(Paint.Style.FILL);
/*
计算针的角度
*/
int hour = Integer.valueOf(Hour_Min_Second[0]) % 12;
int min = Integer.valueOf(Hour_Min_Second[1]) % 60;
int second = Integer.valueOf(Hour_Min_Second[2]) % 60;
float degree_Hour = hour * 30 + min * 0.5f;
float degree_Min = min * 360 / 60;
float degree_Second = second * 360 / 60;
/*
时针
*/
canvas.rotate(degree_Hour,width/2,height/2);
canvas.drawRect(width / 2 - 10,height / 2 - R1 / 2,width / 2 + 10,height / 2 + 40,drawPaint);
/*
分针
*/
canvas.rotate(360 - degree_Hour,width/2,height/2);
canvas.rotate(degree_Min,width/2,height/2);
canvas.drawRect(width / 2 - 10,height / 2 - R1 + 80,width / 2 + 10,height / 2 + 40,drawPaint);
/*
秒针
*/
drawPaint.setColor(Color.RED);
canvas.rotate(360 - degree_Min,width/2,height/2);
canvas.rotate(degree_Second,width/2,height/2);
canvas.drawRect(width / 2 - 5,height / 2 - R1 + 40,width / 2 + 5,height / 2 + 50,drawPaint);
invalidate();
}
}