1. 程式人生 > >Android自定義View——canvas 繪製一個會動的時鐘

Android自定義View——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