文章目录
####1、功能实例
用canvas 绘制一个 会动的 指针式 时钟
####2、代码架构
####3、主要功能代码
activity_main.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context="com.example.menglux.mydrawclock.MainActivity">
<com.example.menglux.mydrawclock.MyClockView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/myclockview"/>
</LinearLayout>
MainActvty.java 文件
package com.example.menglux.mydrawclock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MyClockView.java 文件
package com.example.menglux.mydrawclock;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import java.util.Calendar;
public class MyClockView extends View {
private String TAG = "MyClockView: " ;
private Paint paintCirclePan; //画圆 刻度线
private Paint paintText; //画数字
private Paint paintHour; //画时针
private Paint paintMinute; //画分针
private Paint paintSecond; //画秒针
private Paint paintCenterCir; // 画表芯
private int radias; //圆的半径
private int WidthScan; //屏幕宽度
private int HeightScan; //屏幕高度
private Calendar mcalendar; //获取时间
private static final int NEED_INVALIDATE=0x23;
private Handler mhandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case NEED_INVALIDATE:
//重新获取时间
mcalendar=Calendar.getInstance();
//重新绘制界面
invalidate();//告诉UI主线程重新绘制
//再次发送消息,递归调用,再次监测秒针
mhandler.sendEmptyMessageDelayed(NEED_INVALIDATE, 1000);
break;
default:
break;
}
};
};
public MyClockView(Context context) {
super(context);
}
public MyClockView(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onDraw(Canvas canvas) {
initdata();
drawCircle(canvas);
drawCalibrationLine(canvas);
drawLine(canvas);
}
//绘制 表针
private void drawLine(Canvas canvas) {
paintHour.setStrokeWidth(15); //时间刻度线 线的粗细
paintMinute.setStrokeWidth(10); //分钟刻度线
paintSecond.setStrokeWidth(8); //秒针刻度线
paintCenterCir.setStyle(Paint.Style.FILL); //设置 画笔为实心
//获取系统当时的时间
int hour=mcalendar.get(Calendar.HOUR);
int minute=mcalendar.get(Calendar.MINUTE);
int second=mcalendar.get(Calendar.SECOND);
System.out.println(TAG + "获得的时间 hour: " + hour + " minute: " + minute + " second: " + second);
if (hour > 12) {
hour = hour - 12 ;
}
float hourdregrees= (hour/12f*360) + (minute/60f*30) + 180; //时针旋转的角度
float minudegrees= (minute/60f*360)+ 180; //分针旋转的角度
float senconddegree = (second/60f*360) +180 ; //秒针旋转的角度
System.out.println(TAG + "旋转的角度 hourdregrees: " + hourdregrees + " minudegrees: " + minudegrees + " senconddegree: " + senconddegree);
//绘制表芯
canvas.drawCircle(WidthScan/2, HeightScan/2, 10, paintCenterCir);
//将画布的起点坐标移动到圆心位置
//绘制时针
canvas.save();
canvas.rotate(hourdregrees,WidthScan/2,HeightScan/2); //旋转画布
canvas.drawLine(WidthScan/2,HeightScan/2 - 30,WidthScan/2,HeightScan/2 + 150,paintHour); //画时间刻度线
canvas.restore(); //合并画布
//绘制分针
canvas.save();
canvas.rotate(minudegrees,WidthScan/2,HeightScan/2); //旋转画布
canvas.drawLine(WidthScan/2,HeightScan/2 - 30,WidthScan/2,HeightScan/2 + 220,paintMinute); //画时间刻度线;
canvas.restore(); //合并画布
//绘制秒针
canvas.save();
canvas.rotate(senconddegree,WidthScan/2,HeightScan/2); //旋转画布
canvas.drawLine(WidthScan/2,HeightScan/2 - 30 ,WidthScan/2,HeightScan/2 + 250,paintSecond); //画时间刻度线;
canvas.restore(); //合并画布
}
//画刻度线 和 上面的数字
private void drawCalibrationLine(Canvas canvas) {
paintCirclePan.setStrokeWidth(3);
for (int i = 0 ;i<60 ;i++){
//大点,12点 3点 6点 9点
if (i == 0 || i == 15 || i==30 || i ==45 ){
paintCirclePan.setStrokeWidth(8);
paintCirclePan.setTextSize(60); //设置字体的大小
canvas.drawLine(WidthScan/2,HeightScan/2-radias,WidthScan/2,HeightScan/2-radias + 60,paintCirclePan); //设置 刻度线的 起始位置
String degree = String.valueOf(i/5);
if (i == 0){
degree = "12";
}
canvas.drawText(degree,WidthScan/2-paintCirclePan.measureText(degree)/2,HeightScan/2-WidthScan/2 + 180,paintCirclePan); //设置 刻度线字体
}else if (i % 5 == 0){////整点 刻度线和 数字
paintCirclePan.setStrokeWidth(6);
paintCirclePan.setTextSize(40);
String degree = String.valueOf(i/5);
canvas.drawLine(WidthScan/2,HeightScan/2-radias,WidthScan/2,HeightScan/2-radias + 40,paintCirclePan);
canvas.drawText(degree,WidthScan/2-paintCirclePan.measureText(degree)/2,HeightScan/2-WidthScan/2 + 160,paintCirclePan);
} else{
paintCirclePan.setStrokeWidth(3);
paintCirclePan.setTextSize(20);
canvas.drawLine(WidthScan/2,HeightScan/2-radias,WidthScan/2,HeightScan/2-radias + 20,paintCirclePan);
}
//每次绘制完成后将画布旋转3度
canvas.rotate(6, WidthScan / 2, HeightScan / 2);
}
//保存表盘和刻度的画布
canvas.save();
}
//初始化数据
private void initdata() {
WidthScan = this.getWidth(); //获取 屏幕宽度
HeightScan = this.getHeight(); // 获取屏幕高度
paintCirclePan = new Paint();
paintHour = new Paint();
paintMinute = new Paint();
paintSecond = new Paint();
paintText = new Paint();
paintCenterCir = new Paint();
mcalendar=Calendar.getInstance();//获取时间对象
radias = (Math.min(WidthScan,HeightScan)) / 2;//从高度和宽度中选择一个最小值作为半径的标准
radias = radias - 50; //设置留边距 50
System.out.println(TAG + "圆的半径是: " + radias);
//发送消息,监测秒针
mhandler.sendEmptyMessage(NEED_INVALIDATE);
}
//画圆圈
private void drawCircle(Canvas canvas) {
System.out.println(TAG + "画圆");
paintCirclePan.reset();
paintCirclePan.setColor(Color.BLACK);
paintCirclePan.setStrokeWidth(5);
paintCirclePan.setStyle(Paint.Style.STROKE);
paintCirclePan.setAntiAlias(true);
canvas.drawCircle(WidthScan / 2, HeightScan / 2, radias, paintCirclePan);
}
}
文献参考:
1、Android中Canvas绘图基础详解(附源码下载)
https://blog.csdn.net/iispring/article/details/49770651