Android自定义View——canvas 绘制一个会动的时钟

标签: canvas

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);

    }


}

demo 下载

文献参考:
1、Android中Canvas绘图基础详解(附源码下载)
https://blog.csdn.net/iispring/article/details/49770651

原文链接:加载失败,请重新获取