自定义控件(二) 一个圆形钟表


几天前,又温习了一遍Android群英传,看到了仪表盘这个案例,我看了就想把他再加工一下,给做成一个可以转动的钟表,现在来分析一下,主要界面还是书上的代码,主要的改进就是对指针坐标的计算,这里记录一下,毕竟自己也是刚开始自己写自定义控件。

--------------------------------------------------------------------------------------------------------------------------------

直接上源代码,都有注释很好理解。

package com.aijie.viewandgroupapp.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Administrator on 2016/7/8 0008.
 * 实现一个钟表的View
 */
public class RoundClockView extends View {
    private Context mContext;
    /**
     * 画笔
     */
    private Paint mPaint;

    /**
     * 控件的宽
     */
    private int mWidth;

    /**
     * x方向的圆心坐标
     */
    private int center;

    /**
     * 钟表的半径
     */
    private int radio;
    /**
     * 圆环的宽
     */
    private int strokeWidth = 8;

    /**
     * 当前小时
     */
    private int mCurrentHour;

    /**
     * 当前分钟
     */
    private int mCurrentMinute;

    /**
     * 当前秒
     */
    private int mCurrentSecond;

    /**
     * 时针的长度
     */
    private int hourLineLen;
    /**
     * 分针的长度
     */
    private int minuteLineLen;

    /**
     * 秒针的长度
     */
    private int secondLineLen;

    /**
     * 时针扫过的角度
     */
    private int hourDegree;
    /**
     * 分针扫过的角度
     */
    private int minuteDegree;

    /**
     * 秒针扫过的角度
     */
    private int secondDegree;

    /**
     * 时针,分针,秒针的终点坐标
     */
    private int hourEndX;
    private int hourEndY;

    private int minuteEndX;
    private int minuteEndY;

    private int secondEndX;
    private int secondEndY;

    public RoundClockView(Context context) {
        this(context, null);
    }

    public RoundClockView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundClockView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  // 抗锯齿
        mPaint.setColor(Color.RED);

        new Thread(new Runnable() {
            @Override
            public void run() {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        postInvalidate();
                    }
                };
                timer.schedule(task, 1000, 1000);
            }
        }).start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mWidth = getWidth();

        center = mWidth / 2;  // 圆心 x
        radio = center - strokeWidth / 2;  // 半径

        hourLineLen = radio - 200;  // 时针长度
        minuteLineLen = radio - 120;  // 分针长度
        secondLineLen = radio - 80;  // 秒针长度

        // 画一个中心
        canvas.drawCircle(center, center, 10, mPaint);
        // 设置为空心
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(strokeWidth);
        // 画圆
        canvas.drawCircle(center, center, radio, mPaint);
        // 画刻度
        for (int i = 0; i < 60; i++) {
            if (i % 5 == 0) {
                // 整点
                canvas.drawLine(center, 0, center, 40, mPaint);
                // 画数字
                mPaint.setTextSize(40);
                float textSize = mPaint.getTextSize();
                String clockText = i / 5 == 0 ? "12" : i / 5 + "";
                canvas.drawText(clockText, center - textSize / 2, 80, mPaint);
            } else {
                // 非整点
                canvas.drawLine(center, 0, center, 20, mPaint);
            }
            // 旋转画布
            canvas.rotate(6, center, center);
        }
        // 获取当前时间
        initCurrentTime();

        // 画秒针
        canvas.drawLine(center, center, secondEndX, secondEndY, mPaint);
        // 画分针
        canvas.drawLine(center, center, minuteEndX, minuteEndY, mPaint);
        // 画时针
        mPaint.setStrokeWidth(15);
        canvas.drawLine(center, center, hourEndX, hourEndY, mPaint);
    }

    /**
     * 初始化当前时间,计算时针分针的终点坐标
     */
    private void initCurrentTime() {
        // 获取当前时间
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
        String time = format.format(new Date());
        String result[] = time.split(":");
        mCurrentHour = Integer.parseInt(result[0]);
        mCurrentMinute = Integer.parseInt(result[1]);
        mCurrentSecond = Integer.parseInt(result[2]);

        mCurrentHour = mCurrentHour >= 12 ? mCurrentHour - 12 : mCurrentHour;
        mCurrentMinute = mCurrentHour == 60 ? 0 : mCurrentMinute;
        mCurrentSecond = mCurrentSecond == 60 ? 0 : mCurrentSecond;

        // 秒针角度
        secondDegree = mCurrentSecond * 6;
        // 分针角度
        minuteDegree = mCurrentMinute * 6;
        // 时针角度(还要考虑分针角度)
        hourDegree = mCurrentHour * 30 + Double.valueOf(30 * (minuteDegree*1.0 / 360)).intValue();


        // 换算成弧度
        double hourDeg = Math.PI * hourDegree / 180;
        double minuteDeg = Math.PI * minuteDegree / 180;
        double secondDeg = Math.PI * secondDegree / 180;

        // 计算指针终点坐标
        hourEndX = center + Double.valueOf(hourLineLen * Math.sin(hourDeg)).intValue();
        hourEndY = center - Double.valueOf(hourLineLen * Math.cos(hourDeg)).intValue();

        minuteEndX = center + Double.valueOf(minuteLineLen * Math.sin(minuteDeg)).intValue();
        minuteEndY = center - Double.valueOf(minuteLineLen * Math.cos(minuteDeg)).intValue();

        secondEndX = center + Double.valueOf(secondLineLen * Math.sin(secondDeg)).intValue();
        secondEndY = center - Double.valueOf(secondLineLen * Math.cos(secondDeg)).intValue();

    }

    /**
     * 设置当前时间
     *
     * @param hour   小时
     * @param minute 分钟
     */
    public void setCurrentTime(int hour, int minute) {
        this.mCurrentHour = hour;
        this.mCurrentMinute = minute;
        postInvalidate();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值