简单的自定义View——表盘时钟

来源:互联网 发布:我国能源现状数据 编辑:程序博客网 时间:2024/04/30 17:38

简单的自定义View——表盘时钟

先看看效果

这里写图片描述


先缕一下思路,看下绘制过程

  • 先绘制外面的大圆
  • 再绘制圆心
  • 接着绘制时钟刻度
  • 然后绘制秒指针
  • 绘制分指针
  • 绘制时指针
  • 绘制好后初始化时间,获取时,分,秒
  • 接着用postInvalidateDelayed(1000)方法来定时1秒刷新View

关键点在于使用旋转画布,以及计算圆周长上各点坐标
选择画布canvas.rotate(angle, x, y); // (x,y)旋转点 angle选择角度
圆上点a,b计算公式:
a = r * sin(angle) + x
b = y - r * cos(angle)

绘制过程onDraw方法如下

  • initClock()
  • drawBigCircle(canvas)
  • drawkedu(canvas)
  • drawNumber(canvas)
  • drawHour(canvas, hourAngle)
  • drawMinute(canvas, minuteAngle)
  • drawSecond(canvas, secondAngle)
  • drawSmallCircle(canvas)
  • postInvalidateDelayed(1000)

接着就是实现各种绘制方法了

    // 外面的大圆    private void drawBigCircle(Canvas canvas) {        mPaint.setColor(Color.BLACK);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(Dp2Px(getContext(),1));        canvas.drawCircle(x, y, r, mPaint);    }    // 圆心    private void drawSmallCircle(Canvas canvas) {        mPaint.setColor(Color.RED);        mPaint.setStyle(Paint.Style.FILL);        canvas.drawCircle(x, y, Dp2Px(getContext(),5), mPaint);    }    // 刻度    private void drawkedu(Canvas canvas) {        for (int i = 0; i < 60; i++) {            // 如果i除于5余数为0即比较粗的时刻线            if (i % 5 == 0) {                mPaint.setStyle(Paint.Style.FILL);                mPaint.setStrokeWidth(Dp2Px(getContext(),3));                canvas.drawLine(x, y - r, x, y - r + Dp2Px(getContext(),14), mPaint);            } else {                mPaint.setStyle(Paint.Style.FILL);                mPaint.setStrokeWidth(Dp2Px(getContext(),2));                canvas.drawLine(x, y - r, x, y - r + Dp2Px(getContext(),9), mPaint);            }            canvas.rotate(6, x, y);        }    }    // 刻度上的时间数字    private void drawNumber(Canvas canvas) {        mPaint.setColor(Color.BLACK);        mPaint.setTextSize(Dp2Px(getContext(),14));        mPaint.setTextAlign(Paint.Align.CENTER);  // 设置文本水平居中        float fontHeight = (mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top); // 获取文字高度用于设置文本垂直居中        // 数字离圆心的距离        float distance = r - Dp2Px(getContext(),25);        // 数字的坐标(a,b)        float a, b;        // 每30度写一个数字        for (int i = 0; i < 12; i++) {            a = (float) (distance * Math.sin(i * 30 * (Math.PI / 180)) + x);            b = (float) (y - distance * Math.cos(i * 30 * (Math.PI / 180)));            if (i == 0) {                // 本以为font_height/2即可获得文字一半的高度,实测除以3.5才是,不明觉厉                canvas.drawText("12", a, (float) (b + fontHeight / 3.5), mPaint);             } else {                canvas.drawText(String.valueOf(i), a, (float) (b + fontHeight / 3.5), mPaint);            }        }    }    // 秒指针    private void drawSecond(Canvas canvas, float second) {        mPaint.setColor(Color.RED);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setStrokeWidth(Dp2Px(getContext(),2));        // 指针的长度        float pointLenth = r - Dp2Px(getContext(),15);        // 指针末尾的坐标(a,b)        float a = (float) (pointLenth * Math.sin(second * (Math.PI / 180)) + x);        float b = (float) (y - pointLenth * Math.cos(second * (Math.PI / 180)));        canvas.drawLine(x, y, a, b, mPaint);    }    // 分钟指针    private void drawMinute(Canvas canvas, float minute) {        mPaint.setColor(Color.BLACK);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setStrokeWidth(Dp2Px(getContext(),3));        // 指针的长度        float pointLenth = r - Dp2Px(getContext(),35);        // 指针末尾的坐标(a,b)        float a = (float) (pointLenth * Math.sin(minute * (Math.PI / 180)) + x);        float b = (float) (y - pointLenth * Math.cos(minute * (Math.PI / 180)));        canvas.drawLine(x, y, a, b, mPaint);    }    // 小时指针    private void drawHour(Canvas canvas, float hour) {        mPaint.setColor(Color.BLACK);        mPaint.setStyle(Paint.Style.FILL);        mPaint.setStrokeWidth(Dp2Px(getContext(),4));        // 指针的长度        float pointLenth = r - Dp2Px(getContext(),50);        // 指针末尾的坐标(a,b)        float a = (float) (pointLenth * Math.sin(hour * (Math.PI / 180)) + x);        float b = (float) (y - pointLenth * Math.cos(hour * (Math.PI / 180)));        canvas.drawLine(x, y, a, b, mPaint);    }

初始化时间

    // 获取时间    private void initClock() {        SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");        String time = format.format(new Date(System.currentTimeMillis()));        String[] split = time.split("-");        float hour = Integer.parseInt(split[0]);        float minute = Integer.parseInt(split[1]);        float second = Integer.parseInt(split[2]);        //秒针走过的角度        secondAngle = second * 6;        //分针走过的角度        minuteAngle = minute * 6 + second / 10;        //时针走过的角度        hourAngle = hour * 30 + minute / 10;    }

Dp像素转化

    /**     * 屏幕DP转PX     **/    public int Dp2Px(Context context, float dp) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dp * scale + 0.5f);    }    /**     * 屏幕PX转DP     **/    public int Px2Dp(Context context, float px) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (px / scale + 0.5f);    }

完整源码下载地址https://github.com/LiLinXiang/ClockView

0 0
原创粉丝点击