自定义时钟View,表盘的绘制

来源:互联网 发布:手机快递入库软件 编辑:程序博客网 时间:2024/05/01 00:44

实现的效果图如下:

 main中布局文件:

 <com.example.drawtime.MyClock        android:layout_width="match_parent"        android:layout_height="match_parent" />

values文件夹下新建一个xml文件,定义参数

<resources>    <declare-styleable name="MyView">        <attr name="MyView_color" format="color"/>        <attr name="MyView_radius" format="float"/>    </declare-styleable></resources>

1.自定义一个类 MyClock extends View,并设置统一的入口

public MyClock(Context context) {        this(context, null);    }    public MyClock(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyClock(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0);        //获得xml属性        color = typedArray.getColor(R.styleable.MyView_MyView_color, CIRCLE_CLOCK);        radius = typedArray.getFloat(R.styleable.MyView_MyView_radius, CIRCLE_RADIUS);        typedArray.recycle();    }
2.测量控件的宽高

    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));    }    private int measureHeight(int heightMeasureSpec) {        int mode = MeasureSpec.getMode(heightMeasureSpec);        int size = MeasureSpec.getSize(heightMeasureSpec);        if (mode == MeasureSpec.EXACTLY) {            heightResult = size;        } else {            heightResult = 600;            if (mode == MeasureSpec.AT_MOST) {                heightResult = Math.min(heightResult, size);            }        }        return heightResult;    }    private int measureWidth(int widthMeasureSpec) {        int mode = MeasureSpec.getMode(widthMeasureSpec);        int size = MeasureSpec.getSize(widthMeasureSpec);        if (mode == MeasureSpec.EXACTLY) {            widthResult = size;        } else {            widthResult = 600;//给一个默认的宽度            if (mode == MeasureSpec.AT_MOST) {                widthResult = Math.min(widthResult, size);            }        }        return widthResult;    }
3.----------------------现在就要开始绘制了---------------------------

我把他们封装为方法

@Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制表盘        BiaoPan(canvas);        //绘制logo        Logo(canvas);        //绘制数字时间        Time(canvas);        //画刻度        drgree(canvas);        //画表盘时间数字        HourText(canvas);        mHandler.sendEmptyMessage(HANDLER_MSG);        //画时针        canvas.save();        hour(canvas);        canvas.restore();        //画分针        canvas.save();        minutes(canvas);        canvas.restore();        //画秒针        canvas.save();        second(canvas);        canvas.restore();        //画中间小点        Point(canvas);    }
3.1绘制表盘

private void BiaoPan(Canvas canvas) {        mBiaoPan = new Paint();        mBiaoPan.setAntiAlias(true);        canvas.translate(widthResult / 2, heightResult / 2);        mBiaoPan.setStyle(Paint.Style.STROKE);        mBiaoPan.setColor(color);        mBiaoPan.setStrokeWidth(2);        canvas.drawCircle(0, 0, radius, mBiaoPan);    }
3.2绘制Logo,正负代表方向

private void Logo(Canvas canvas) {        mLogoPaint = new TextPaint();        mLogoPaint.setColor(Color.parseColor("#FF4081"));        mLogoPaint.setAntiAlias(true);        mLogoPaint.setStyle(Paint.Style.STROKE);        mLogoPaint.setStrokeWidth(2);        mLogoPaint.setTextSize(50);        float textwith = mLogoPaint.measureText(BIAO_LOGO);        canvas.drawText(BIAO_LOGO, -textwith / 2, -radius / 5 * 2, mLogoPaint);    }
3.3绘制数字的时间,默认 00:00:00

private void Time(Canvas canvas) {        mTimePaint = new Paint();        mTimePaint.setAntiAlias(true);        mTimePaint.setColor(Color.GREEN);        mTimePaint.setStyle(Paint.Style.FILL);        mTimePaint.setTextSize(45);        /**根据实际情况我们需要判断下时分秒的数字是不是小于10,如果是前面补一位0*/        if (mSecond < 10) {            replaceMsecond = "0" + String.valueOf(mSecond).replace(".0", "");        } else {            replaceMsecond = String.valueOf(mSecond).replace(".0", "");        }        if (mMinutes < 10) {            replaceMminutes = "0" + String.valueOf(mMinutes).replace(".0", "");        } else {            replaceMminutes = String.valueOf(mMinutes).replace(".0", "");        }        if (mHour < 10) {            replaceMhour = "0" + String.valueOf(mHour).replace(".0", "");        } else {            replaceMhour = String.valueOf(mHour).replace(".0", "");        }        float v = mTimePaint.measureText(replaceMhour + replaceMminutes + replaceMsecond + ":" + ":");        canvas.drawText(replaceMhour + ":" + replaceMminutes + ":" + replaceMsecond, -v / 2, radius / 3 * 2, mTimePaint);    }
3.4绘制刻度线(让画布旋转)

private void drgree(Canvas canvas) {        mDegreePaint = new Paint();        mDegreePaint.setAntiAlias(true);        mDegreePaint.setStyle(Paint.Style.FILL);        mDegreePaint.setColor(Color.BLACK);        mDegreePaint.setStrokeWidth(5);        int count = 60;        for (int i = 0; i < count; i++) {            if (i % 5 == 0) {                canvas.drawLine(0, radius, 0, radius - 40, mDegreePaint);            } else {                canvas.drawLine(0, radius, 0, radius - 15, mDegreePaint);            }            canvas.rotate(360 / count, 0f, 0f);        }    }
3.5 画表盘上的数字

private void HourText(Canvas canvas) {        mHourTextPaint = new Paint();        mHourTextPaint.setStyle(Paint.Style.FILL);        mHourTextPaint.setStrokeWidth(2);        mHourTextPaint.setAntiAlias(true);        mHourTextPaint.setTextSize(55);        mHourTextPaint.setColor(Color.DKGRAY);        mHourTextPaint.setTextAlign(Paint.Align.CENTER);        float textheight = mHourTextPaint.getFontMetrics().bottom - mHourTextPaint.getFontMetrics().top;        float distance = radius - 70;        float a, b;        for (int i = 0; i < 12; i++) {            a = (float) (distance * Math.sin(i * 30 * Math.PI / 180));            b = (float) (distance * Math.cos(i * 30 * Math.PI / 180));            if (i == 0) {                canvas.drawText("12", a, -b + textheight / 3, mHourTextPaint);            } else {                canvas.drawText(String.valueOf(i), a, -b + textheight / 3, mHourTextPaint);            }        }    }
3.6 发送一条空消息,让时间数字,走起来

@Override    public boolean handleMessage(Message message) {        switch (message.what) {            case HANDLER_MSG:                invalidate();                long time = System.currentTimeMillis();                mSecond =  (time / 1000 % 60);                mMinutes =  (time / 1000 / 60 % 60);                mHour = (time / 1000 / 60 / 60 + 8) % 12;                break;        }        return true;    }

3.7画时针分针秒针(必须要先保存之前的画的,不然会一起动)

private void hour(Canvas canvas) {        mHourPaint = new Paint();        mHourPaint.setStrokeWidth(10);        mHourPaint.setAntiAlias(true);        mHourPaint.setStyle(Paint.Style.FILL);        mHourPaint.setColor(Color.RED);        canvas.rotate(mHour * 30 + mMinutes / 60 * 30, 0, 0);//其中mMinutes/60*30为时钟偏移的角度        canvas.drawLine(0, 20, 0, -(radius -320), mHourPaint);    }
private void minutes(Canvas canvas) {        mMinutesPaint = new Paint();        mMinutesPaint.setStrokeWidth(8);        mMinutesPaint.setAntiAlias(true);        mMinutesPaint.setColor(Color.BLUE);        mMinutesPaint.setStyle(Paint.Style.FILL);        canvas.rotate(mMinutes * 6, 0, 0);        canvas.drawLine(0, 20, 0, -(radius - 200), mMinutesPaint);    }
private void second(Canvas canvas) {        //画秒针        mSecondPaint = new Paint();        mSecondPaint.setStrokeWidth(5);        mSecondPaint.setAntiAlias(true);//设置抗锯齿        mSecondPaint.setColor(Color.GREEN);        mSecondPaint.setStyle(Paint.Style.FILL);        canvas.rotate(mSecond * 6, 0, 0);        canvas.drawLine(0, 30, 0, -(radius - 100), mSecondPaint);    }




3.8 最后在中心画点把指针覆盖

private void Point(Canvas canvas) {        mPointPaint = new Paint();        mPointPaint.setStrokeWidth(5);        mPointPaint.setStyle(Paint.Style.FILL);        mPointPaint.setColor(Color.BLACK);        canvas.drawCircle(0, 0, 12, mPointPaint);    }


直接的粘的代码,看的不是很清楚,慢慢看咯害羞




0 0
原创粉丝点击