记录一个时钟控件

138 阅读2分钟

项目开发需要一个时钟控件,三个指针使用图片

自定义View代码如下:

/**
 * CreateTime:
 * Desc:
 * Version:
 */

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

import com.youloft.meridiansleep.R;

import java.util.Calendar;

/**
 * 钟表控件
 */

public class KKClockView extends View {
    //画笔
    private Paint mPaint;

    //控件宽度
    public int mWidth;

    //控件高度
    public int mHeght;
    public int mInnerColor;
    public float mInnerWidth;
    public float mInnerRadius;


    public Bitmap hourBitmap;
    public Bitmap minuteBitmap;
    public Bitmap secondBitmap;

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

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

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

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.KKClockView);
        int hourResId = typedArray.getResourceId(R.styleable.KKClockView_KKHourResId, R.mipmap.clock_hour);
        int minuteResId = typedArray.getResourceId(R.styleable.KKClockView_KKMinuteResId, R.mipmap.clock_minute);
        int secondResId = typedArray.getResourceId(R.styleable.KKClockView_KKSecondResId, R.mipmap.clock_second);
        mInnerColor = typedArray.getColor(R.styleable.KKClockView_KKInnerColor, Color.parseColor("#54402F"));
        mInnerWidth = typedArray.getDimension(R.styleable.KKClockView_KKInnerWidth, 10);
        mInnerRadius = typedArray.getDimension(R.styleable.KKClockView_KKInnerRadius, 15);

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

        hourBitmap = BitmapFactory.decodeResource(getResources(), hourResId);
        minuteBitmap = BitmapFactory.decodeResource(getResources(), minuteResId);
        secondBitmap = BitmapFactory.decodeResource(getResources(), secondResId);

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        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);
        //设置宽高、半径
        mWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        mHeght = getMeasuredHeight() - getPaddingBottom() - getPaddingTop();
        //绘制指针
        drawPointer(canvas);
        //刷新ui
        postInvalidateDelayed(300);
    }


    /**
     * 绘制指针
     *
     * @param canvas
     */
    private void drawPointer(Canvas canvas) {
        Calendar mCalendar = Calendar.getInstance();
        //获取当前小时数 这里小时是24小时制的  如果是12小时制改为Calendar.HOUR
        int hours = mCalendar.get(Calendar.HOUR_OF_DAY);
        //获取当前分钟数
        int minutes = mCalendar.get(Calendar.MINUTE);
        //获取当前秒数
        int seconds = mCalendar.get(Calendar.SECOND);


        //绘制时针
        canvas.save();
        //这里计算时针需要旋转的角度 实现原理是计算出一共多少分钟除以60计算出真实的小时数(带有小数,为了更加准确计算度数),已知24小时是360度,现在求出了实际小时数比例求出角度
        Float hoursAngle = (hours * 60 + minutes) / 60f / 24f * 360;//如果是12小时制的 这里的24需要修改为12
        canvas.rotate(hoursAngle, mWidth / 2, mHeght / 2);
        canvas.drawBitmap(hourBitmap, mWidth / 2 - hourBitmap.getWidth() / 2, mHeght / 2 - hourBitmap.getHeight() - mInnerRadius, mPaint);
        canvas.restore();

        //绘制分针
        canvas.save();
        //这里计算分针需要旋转的角度  60分钟360度,求出实际分钟数所占的度数
        Float minutesAngle = (minutes * 60 + seconds) / 60f / 60f * 360;
        canvas.rotate(minutesAngle, mWidth / 2, mHeght / 2);
        canvas.drawBitmap(minuteBitmap, mWidth / 2 - minuteBitmap.getWidth() / 2, mHeght / 2 - minuteBitmap.getHeight() - mInnerRadius, mPaint);
        canvas.restore();

        //绘制秒针
        canvas.save();
        //这里计算秒针需要旋转的角度  60秒360度,求出实际秒数所占的度数
        Float secondAngle = seconds / 60f * 360;
        canvas.rotate(secondAngle, mWidth / 2, mHeght / 2);
        canvas.drawBitmap(secondBitmap, mWidth / 2 - secondBitmap.getWidth() / 2, mHeght / 2 - secondBitmap.getHeight() - mInnerRadius, mPaint);
        canvas.restore();

        //绘制中间的圆圈
        canvas.save();
        mPaint.setColor(mInnerColor);
        mPaint.setStrokeWidth(mInnerWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(mWidth / 2, mHeght / 2, mInnerRadius, mPaint);
        canvas.restore();
    }

}

自定义属性如下:

<declare-styleable name="KKClockView">
    <attr name="KKHourResId" format="reference"/>
    <attr name="KKMinuteResId" format="reference"/>
    <attr name="KKSecondResId" format="reference"/>
    <attr name="KKInnerRadius" format="dimension"/>
    <attr name="KKInnerColor" format="color"/>
    <attr name="KKInnerWidth" format="dimension"/>
</declare-styleable>

使用

<com.youloft.meridiansleep.view.KKClockView
    android:id="@+id/cl_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:KKHourResId="@mipmap/clock_hour_min"
    app:KKInnerRadius="3dp"
    app:KKInnerWidth="2dp"
    app:KKMinuteResId="@mipmap/clock_minute_min"
    app:KKSecondResId="@mipmap/clock_second_min" />