自定义view(二)之钟表

作者: 记得不要忘 | 来源:发表于2017-09-14 14:18 被阅读74次

    有时间学习还要有时间总结,感觉学习真是痛苦,痛不欲生、痛苦并快乐着,学会了如果不记下来那么最后的结果就是忘记了,啥也不记得了,以后忘了也没有个地方去查,所以现在我就要做这个工作。其实做表这个demo是17年的8月31号,本来我其实就想画了表盘呢(也是没啥志气),没想到花完感觉空落落的,光秃秃的也不好看,我就想找找看看大家大家的思路是啥,怎么能让那个秒针动弹,然后还真有很简单的方法 postInvalidateDelayed(1000)(我试过这个方法,写1也是1秒,还不知道原理)。如果解决了这个问题那么做一个钟表很简单的,大概思路是这样的:
    1.先把画笔的中点移到屏幕中心,画圆,外边画一个方,然后白色的背景就是表盘了,画刻度
    2.计算秒针、分针、时针的角度,这就完成了。

    先上一个图吧

    表的图

    思路讲完了,现在就是coding了,顺便也说一下一些方法的用法

    这就是第一步,把基本的表盘给花出来
    private void drawCircle(Canvas canvas) {
        r = (float) (Math.min(mWidth, mHeight)/2 *0.8);
        canvas.translate(mWidth/2, mHeight /2);//移动画布中心点到屏幕中央
        paint.setColor(getResources().getColor(R.color.brown));//设置画笔的颜色
        canvas.drawRect(-r-20,-r-20,r+20,r+20,paint);//画一个正方形,就是外边褐色的框
        paint.setColor(getResources().getColor(R.color.black));
        paint.setStyle(Paint.Style.FILL);//设置画笔是实心的,画出表盘的圆来
        paint.setColor(getResources().getColor(R.color.white));
        canvas.drawCircle(0,0,r+5,paint);
    
        paint.setStyle(Paint.Style.STROKE);//设置画笔为描边
        paint.setColor(getResources().getColor(R.color.black));
        paint.setStrokeWidth(1);
        paint.setTextSize(15);
        canvas.save();//保存画布
    
        int lineWidth;
        for (int i = 0; i < 60; i++) {//现在就是要画出表盘的那些个刻度
            if (i % 5 == 0) {//是画整点的刻度的,比如12,1,2,3点
                paint.setStrokeWidth(3);//设置一下画笔的宽度
                lineWidth = 20;//设置整点刻度的线长度
                String text = String.valueOf(12 - i/5);//计算当前要填写的数字
                Rect textBound = new Rect();
                paint.getTextBounds(text, 0, text.length(), textBound);
                canvas.save();
                paint.setStrokeWidth(2);
                paint.setTextSize(25);
                paint.setStyle(Paint.Style.FILL);
                canvas.translate(0,10+lineWidth-r+(textBound.bottom - textBound.top));
                canvas.rotate(6 * i);//做一下画布的旋转,这样数字的显示就是正常的哩
                canvas.drawText(text, -(textBound.right - textBound.left) / 2,10, paint);
                canvas.restore();
            }else{//画每一分的小刻度的
                paint.setStrokeWidth(1);
                lineWidth = 10;
                paint.setStrokeWidth(1);
            }
            canvas.drawLine(0,-r+10,0,10+lineWidth-r,paint);
            canvas.rotate(-360/60);//画布逆时针赚
        }
        canvas.restore();
    }
    
    表盘的图

    表盘花完了就是做最重要的一步了,就是让表动起来,怎么让表动,就是定时的刷新,怎么做定时刷新,其实定时刷新还挺多的用Timer+handler等等一些,现在我就用一个简单的postInvalidateDelayed()方法。

    /**
     * 表的指针
     * @param canvas 第一版使用的是60分的,每一秒6度
     */
    private void drawPointer(Canvas canvas){
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY); //时
        int minute = calendar.get(Calendar.MINUTE); //分
        int second = calendar.get(Calendar.SECOND); //秒
        int angleHour = ((hour % 60) * 360 / 12); //时针转过的角度
        int angleMinute = minute * 360 / 60; //分针转过的角度
        int angleSecond = second * 360 / 60; //秒针转过的角度
        paint.setStyle(Paint.Style.FILL);
    
    
        canvas.save();//分针转动
        paint.setColor(getResources().getColor(R.color.black));
        canvas.rotate(angleMinute);//旋转画布 angleMinute的角度
        RectF rectFMinute = new RectF(-4, -r*2/3,  4, 30);
        canvas.drawRoundRect(rectFMinute, 10, 10, paint);
        canvas.restore();
    
        int hourMinute = angleMinute / (6 * 12);//时针转动
        if (hourMinute > 0) {//主要实现让时针12分钟转动一格,
            // 防止时针一小时转一大格不好看
            canvas.save();
            canvas.rotate(angleHour+hourMinute * 6);
            RectF rectFHour1 = new RectF(-6, -r/2,  6, 30);
            canvas.drawRoundRect(rectFHour1, 10, 10, paint);
            canvas.restore();
        }else{
            canvas.save();
            canvas.rotate(angleHour);
            RectF rectFHour = new RectF(-6, -r/2,  6, 30);
            canvas.drawRoundRect(rectFHour, 10, 10, paint);
            canvas.restore();
        }
    
        canvas.save();//秒针转动
        paint.setColor(getResources().getColor(R.color.red));
        canvas.drawCircle(0,0,15,paint);
        canvas.rotate(angleSecond);
        RectF rectFSecond = new RectF(-3, -r+5,  3, 30);
        canvas.drawRoundRect(rectFSecond, 10, 10, paint);
        canvas.restore();
    }
    

    这个是我刚开始的写法,如果这么写就会有一个不好看的地方就是分针每次一小格,感觉太明显了,当然这个问题不是我发现的,是我女朋友说的:那个分针怎么那么转呀,一下跳那么大老远。没办法,女朋友都容忍不了说明是大问题,我就想要不和分针一样,然后就把一小格继续细分让分针实现成一分钟慢慢的调一格也就是6度,12秒钟调一度,5个12秒刚好事一格。

    /**
     * 表的指针
     * @param canvas 第二版使用的是每一分下边再细分6度,这样就可以让指针变化的范围更小
     */
    private void drawPointerSecond(Canvas canvas){
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY); //时
        int minute = calendar.get(Calendar.MINUTE); //分
        int second = calendar.get(Calendar.SECOND); //秒
        int angleHour = ((hour % 60) * 360 / 12); //时针转过的角度
        int angleMinute = minute * 360 / 60; //分针转过的角度
        int angleSecond = second * 360 / 60; //秒针转过的角度
        paint.setStyle(Paint.Style.FILL);
    
    
        int minuteSecond = angleSecond/(6*10);
        if (minuteSecond>0) {
    
            canvas.save();//分针转动
            paint.setColor(getResources().getColor(R.color.black));
            canvas.rotate(angleMinute + minuteSecond);//旋转画布 angleMinute的角度
            RectF rectFMinute = new RectF(-4, -r*2/3,  4, 30);
            canvas.drawRoundRect(rectFMinute, 10, 10, paint);
            canvas.restore();
    
        }else{
    
            canvas.save();//分针转动
            paint.setColor(getResources().getColor(R.color.black));
            canvas.rotate(angleMinute);//旋转画布 angleMinute的角度
            RectF rectFMinute = new RectF(-4, -r*2/3,  4, 30);
            canvas.drawRoundRect(rectFMinute, 10, 10, paint);
            canvas.restore();
    
        }
    
        
        int hourMinute = angleMinute / (6 * 12);//时针转动
        if (hourMinute > 0) {//主要实现让时针12分钟转动一格,
            // 防止时针一小时转一大格不好看
            canvas.save();
            canvas.rotate(angleHour+hourMinute * 6);
            RectF rectFHour1 = new RectF(-6, -r/2,  6, 30);
            canvas.drawRoundRect(rectFHour1, 10, 10, paint);
            canvas.restore();
        }else{
            canvas.save();
            canvas.rotate(angleHour);
            RectF rectFHour = new RectF(-6, -r/2,  6, 30);
            canvas.drawRoundRect(rectFHour, 10, 10, paint);
            canvas.restore();
        }
    
    
        canvas.save();//秒针转动
        paint.setColor(getResources().getColor(R.color.red));
        canvas.drawCircle(0,0,15,paint);
        canvas.rotate(angleSecond);
        RectF rectFSecond = new RectF(-3, -r+5,  3, 30);
        canvas.drawRoundRect(rectFSecond, 10, 10, paint);
        canvas.restore();
    }
    

    表就做完了,只要引用到布局文件里就可以了。 这是我的git博客,这里是我的git地址欢迎大家star和fork

    相关文章

      网友评论

        本文标题:自定义view(二)之钟表

        本文链接:https://www.haomeiwen.com/subject/hxrdsxtx.html