Android自定义一个属于自己的时间钟表

转载https://blog.csdn.net/u014741977/article/details/53582090

感谢博主的分析值得学习,同时优化了下你的代码.

package com.example.timeclock;

import java.util.Calendar;

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

/**
 * 
 * 
 * <p></p>
 * 下午3:14:19
 *
 * @author ZH-SW-Mengyf
 * @version 1.0.0
 */
public class ClockView extends View {
    /** 文字画笔对象 */
    private  Paint mTextPaint;
    /** 圆,指针,刻度画笔 */
    private  Paint mPaint;
    /** 半径 */
    public float mRadius;
    /** 外圆的颜色 */
    public int mCircleColor;
    /** 外圆的宽度 */
    public float mCircleWidth;
    /** 文字的大小 */
    public float mTextSize;
    /** 文字的颜色 */
    public int mTextColor;
    /** 大刻度颜色 */
    public int mBigScaleColor;
    /** 中刻度 */
    public int mMiddlecaleColor;
    /** 小刻度颜色 */
    public int mSmallScaleColor;
    /** 时针颜色 */
    public int mHourHandColor;
    /** 分针颜色 */
    public int mMinuteHandColor;
    /** 秒针颜色 */
    public int mSecondHandColor;
    /** 时针宽度 */
    public float mHourHandWidth;
    /** 分针宽度 */
    public float mMinuteHandWidth;
    /** 秒针宽度 */
    public float mSecondHandWidth;
    /** 控件宽度 */
    public int mWidth;
    /** 控件高度 */
    public int mHeght;
    /** 控件宽度一半 */
	private int mWidthHalf;
	/** 控件高度 一半*/
	private int mHeghtHalf;

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

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

    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.ClockView);
        mRadius=typedArray.getDimension(R.styleable.ClockView_mRadius,400);
        mCircleColor=typedArray.getColor(R.styleable.ClockView_mCircleColor, Color.WHITE);
        mCircleWidth=typedArray.getDimension(R.styleable.ClockView_mCircleWidth,20);
        mTextSize=typedArray.getDimension(R.styleable.ClockView_mCircleWidth,40);
        mTextColor=typedArray.getColor(R.styleable.ClockView_mTextColor,Color.DKGRAY);
        mBigScaleColor=typedArray.getColor(R.styleable.ClockView_mBigScaleColor,Color.BLACK);
        mSmallScaleColor=typedArray.getColor(R.styleable.ClockView_mSmallScaleColor,Color.RED);
        mMiddlecaleColor=typedArray.getColor(R.styleable.ClockView_mMiddlecaleColor,Color.BLACK);
        mHourHandColor=typedArray.getColor(R.styleable.ClockView_mHourHandColor,Color.BLACK);
        mMinuteHandColor=typedArray.getColor(R.styleable.ClockView_mMinuteHandColor,Color.BLACK);
        mSecondHandColor=typedArray.getColor(R.styleable.ClockView_mSecondHandColor,Color.BLACK);
        mHourHandWidth=typedArray.getDimension(R.styleable.ClockView_mHourHandWidth,20);
        mMinuteHandWidth=typedArray.getDimension(R.styleable.ClockView_mMinuteHandWidth,10);
        mSecondHandWidth=typedArray.getDimension(R.styleable.ClockView_mSecondHandWidth,5);

		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Paint.Style.STROKE);

		mTextPaint = new Paint();
		mTextPaint.setAntiAlias(true);
		mTextPaint.setStyle(Paint.Style.STROKE);
		mTextPaint.setTextSize(mTextSize);
		mTextPaint.setColor(mTextColor);
		
		typedArray.recycle();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    	super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    	 //设置宽高、半径
		mWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
		mHeght = getMeasuredHeight() - getPaddingBottom() - getPaddingTop();
		mWidthHalf = mWidth / 2;
		mHeghtHalf = mHeght / 2;
		mRadius = Math.min(mWidth, mHeght);
		
        setMeasuredDimension(measureSize(widthMeasureSpec),measureSize(heightMeasureSpec));
    }

    private int measureSize(int mMeasureSpec) {
        int result;
		int mode = MeasureSpec.getMode(mMeasureSpec);
		int size = MeasureSpec.getSize(mMeasureSpec);
		if (mode == MeasureSpec.EXACTLY) {//更具父类填充
			result = size;
        }else{
			result = 400;
			if (mode == MeasureSpec.AT_MOST) {
				result = Math.min(result, size);
			}
        }
        return  result;
    }

    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //首先绘制圆
        drawCircle(canvas);
        //绘制刻度
        drawScale(canvas);
        //绘制指针
        drawPointer(canvas);
        //发送消息刷新ui
        postInvalidateDelayed(1000);
    }

    /**
     * 画圆
     * @param canvas
     */
    private void drawCircle(Canvas canvas) {
        mPaint.setStrokeWidth(mCircleWidth);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(mCircleColor);
        canvas.drawCircle(mWidthHalf,mWidthHalf,mRadius,mPaint);
    }

    /**
     * 刻度和文字
     * @param canvas
     */
    private void drawScale(Canvas canvas) {
		for (int i = 0; i < 60; i++) {
            //设置大刻度
        	float startX = mWidthHalf;
        	float startY = mHeghtHalf - mWidthHalf + mCircleWidth / 2;
        	float stopX = mWidthHalf;
        	float stopY = mHeghtHalf - mWidthHalf + mCircleWidth / 2;
        	
			if (i == 0 || i == 15 || i == 30 || i == 45) {
                mPaint.setStrokeWidth(6);
                mPaint.setColor(mBigScaleColor);
				canvas.drawLine(startX, startY, stopX, stopY + 60, mPaint);
                
				String scaleTv = String.valueOf(i == 0 ? 12 : i / 5);
				float x = mWidthHalf - mTextPaint.measureText(scaleTv) / 2;
				float y = mHeghtHalf - mWidthHalf + mCircleWidth / 2;
				canvas.drawText(scaleTv, x, y + 95, mTextPaint);
				
            }else if (i==5||i==10||i==20||i==25||i==35||i==40||i==50||i==55)
            //设置中刻度
            {
                mPaint.setStrokeWidth(4);
                mPaint.setColor(mMiddlecaleColor);
				canvas.drawLine(startX, startY, stopX, stopY + 40, mPaint);
				String scaleTv = String.valueOf(i / 5);
				
				float x = mWidthHalf - mTextPaint.measureText(scaleTv) / 2;
				float y = mHeghtHalf - mWidthHalf + mCircleWidth / 2;
				canvas.drawText(scaleTv, x, y + 75, mTextPaint);

            }else
            //设置小刻度
            {
                mPaint.setColor(mSmallScaleColor);
                mPaint.setStrokeWidth(2);
				canvas.drawLine(startX, startY, stopX, stopY + 30, mPaint);
            }
            canvas.rotate(6,mWidthHalf,mHeghtHalf);
        }
    }


    /**
     * 绘制指针
     * @param canvas
     */
    private void drawPointer(Canvas canvas) {
		Calendar mCalendar = Calendar.getInstance();
        //获取当前小时数
        int hours = mCalendar.get(Calendar.HOUR);
        //获取当前分钟数
        int minutes = mCalendar.get(Calendar.MINUTE);
        //获取当前秒数
        int seconds=mCalendar.get(Calendar.SECOND);
        //
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        
        //绘制时针
        canvas.save();
        mPaint.setColor(mHourHandColor);
        mPaint.setStrokeWidth(mHourHandWidth);
        //这里计算时针需要旋转的角度 实现原理是计算出一共多少分钟除以60计算出真实的小时数(带有小数,为了更加准确计算度数),已知12小时是360度,现在求出了实际小时数比例求出角度
		Float hoursAngle = (hours * 60 + minutes) / 60f / 12f * 360;
        canvas.rotate(hoursAngle, mWidthHalf, mHeghtHalf);
        canvas.drawLine(mWidthHalf, mHeghtHalf * 0.5f, mWidthHalf, mHeghtHalf * 1.15f, mPaint);
        canvas.restore();

        //绘制分针
        canvas.save();
        mPaint.setColor(mMinuteHandColor);
        mPaint.setStrokeWidth(mMinuteHandWidth);
        //这里计算分针需要旋转的角度  60分钟360度,求出实际分钟数所占的度数
		Float minutesAngle = (minutes * 60 + seconds) / 60f / 60f * 360;
        canvas.rotate(minutesAngle, mWidthHalf, mHeghtHalf);
        canvas.drawLine(mWidthHalf, mHeghtHalf * 0.3f, mWidthHalf,  mHeghtHalf * 1.15f, mPaint);
        canvas.restore();

        //绘制中间的圆圈
		canvas.save();
		mPaint.setColor(mSecondHandColor);
		mPaint.setStrokeWidth(mSecondHandWidth);
		mPaint.setStyle(Paint.Style.FILL);
		canvas.drawCircle(mWidthHalf, mHeghtHalf, 20, mPaint);
		canvas.restore();

        //绘制秒针
        canvas.save();
        mPaint.setColor(mSecondHandColor);
        mPaint.setStrokeWidth(mSecondHandWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        //这里计算秒针需要旋转的角度  60秒360度,求出实际秒数所占的度数
		Float secondAngle = seconds / 60f * 360;
        canvas.rotate(secondAngle, mWidthHalf, mHeghtHalf);
        canvas.drawLine(mWidthHalf, mHeghtHalf * 0.2f, mWidthHalf,  mHeghtHalf * 1.20f, mPaint);
        canvas.restore();
    }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值