Android时钟效果自定义view实现

对于时钟的这样一个效果控件,一般在开发时候,大多情况为了满足设计师的需要,都是要自定义的,因此,在实现效果之前,需要理清思路,思路很重要,思路清楚了,写代码就轻松很多。

现在我们就先进行时钟分钟秒钟的换算,具体如下:

秒针每转一圈,是360度,那么秒针转一圈分针则转6度,

由此可知秒针每转一秒是6度,秒针每转六度则分针转0.1度,

同理可得秒针每转一秒,时针转动0.008度。

至此理论上的时分秒确定,接下来就是确定自定义View时候的,开始布局了。

自定义View的创建我就不多讲了,直接上核心代码,后面整个项目会上传,需要的可以自行下载。

首先是画一个圆代码如下:

   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        Log.e("onDraw","onDraw");
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(4);
        canvas.drawCircle(width,height,mRadiu,paint);
}

然后开始画刻度,时针,分针,秒针,

刻度时针和分针的画法需要用到一点三角函数的知识,

代码里面有,我就直接上代码了,不写公式了,具体代码如下:

   //秒针的坐标
    private float startSx;
    private float startSy;
    private float endSx;
    private float endSy;
    private float degreeS = 0;
    //分针的坐标
    private float startMx;
    private float startMy;
    private float endMx;
    private float endMy;
    private float degreeM = 0;
    //时针的坐标
    private float startHx;
    private float startHy;
    private float endHx;
    private float endHy;
    private float degreeH = 0;

    private boolean isStart;

  //秒针线程,控制秒针绘制
        new Thread(){
            @Override
            public void run() {
                while (isStart) {
                    //判断秒针分针时针转满一圈
                    if (degreeS > 357){
                        degreeS = 0;
                    }
                    if (degreeM>357){
                        degreeM = 0;
                    }
                    if (degreeH>357){
                        degreeH = 0;
                    }
                    //线程是每一秒绘制一次,则每秒增加Math.PI/30度,如果睡眠时间是100,则每秒增加Math.PI/300度,分针和时针同理,也根据线程睡眠时间进行换算就可以了
                    degreeS += Math.PI/30;
                    //秒针每转一秒,分针转的角度为0.1度
                    degreeM += Math.PI/1800;
                    //秒针每转一秒,时针转动0.008度
                    degreeH += Math.PI/22500;
                    postInvalidate();
                    try {
                        //通过线程睡眠控制绘图频率
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();


   for(int i= 0;i<60;i++){
            double degree = (Math.PI/30)*i;
            //控制始终表格刻度的长度
            int length = 10;
            switch (i){
                case 0:
                case 5:
                case 10:
                case 15:
                case 20:
                case 25:
                case 30:
                case 35:
                case 40:
                case 45:
                case 50: length = 20;
            }
            //计算起始坐标
            float startX = (float) (width+(mRadiu*Math.sin(degree)));
            float startY = (float) (getHeight()/2-mRadiu+mRadiu*(1-Math.cos(degree)));
            //计算结束坐标
            float endX = (float) (width+(mRadiu-length)*Math.sin(degree));
            float endY = (float) (getHeight()/2-mRadiu+(mRadiu-length)*(1-Math.cos(degree))+length);
//            Log.e("circle","mRadiu*Math.sin(i*30) = "+mRadiu*Math.sin(degree)+ " mRadiu*(1-Math.cos(i*3))= "+mRadiu*(1-Math.cos(degree)));
//            Log.e("circle","startX = "+startX+ " startY = "+startY);
//            Log.e("circle","endX = "+endX+ " endY = "+endY);
            canvas.drawLine(startX,startY,endX,endY,paint);
        }

        //画中心实心黑圆圈
        canvas.drawCircle(width,height,10,paint);



        //画分针
        startMx = (float) (width+((mRadiu-70)*Math.sin(degreeM)));
        startMy = (float) (getHeight()/2-(mRadiu-70)*Math.cos(degreeM));
        endMx = width;
        endMy = height;
        paint.setStrokeWidth(8);
        paint.setColor(Color.BLACK);
//        Log.e("circle","degreeM = "+degreeM+" ((mRadiu-60)*Math.sin(degreeM)) = "+((mRadiu-60)*Math.sin(degreeM))+ " (mRadiu-60)*Math.cos(degreeM)= "+(getHeight()/2-(mRadiu-60)*Math.cos(degreeM)));
        canvas.drawLine(startMx,startMy,endMx,endMy,paint);

        //画时针
        startHx = (float) (width+((mRadiu-90)*Math.sin(degreeH)));
        startHy = (float) (getHeight()/2-(mRadiu-90)*Math.cos(degreeH));
        endHx = width;
        endHy = height;
        paint.setStrokeWidth(10);
        canvas.drawLine(startHx,startHy,endHx,endHy,paint);

        //画秒针
        startSx = (float) (width+((mRadiu-50)*Math.sin(degreeS)));
        startSy = (float) (getHeight()/2-(mRadiu-50)*Math.cos(degreeS));
//        Log.e("circle","degreeS = "+degreeS+" ((mRadiu-50)*Math.sin(degreeS)) = "+((mRadiu-50)*Math.sin(degreeS))+ " (mRadiu-50)*Math.cos(degreeS)= "+(mRadiu-50)*Math.cos(degreeS));
        endSx = width;
        endSy = height;
        paint.setStrokeWidth(5);
        paint.setColor(Color.RED);
        canvas.drawLine(startSx,startSy,endSx,endSy,paint);

至此,一个基本的自定义时钟就完成了,

效果如下:

还有很多完善空间,比如,在刻度加上时间数,但是由于时间比较紧,就先这样了。


项目下载链接https://download.csdn.net/download/u013704998/75861702icon-default.png?t=LBL2https://download.csdn.net/download/u013704998/75861702

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖摸鱼专业户

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值