Android自定义View绘制闹钟

原创 2015年08月29日 17:16:21

Android自定义View绘制闹钟

本文简单实现了一个闹钟,扩展View,Canvas绘制
效果如下:
这里写图片描述

代码如下:

package com.gaofeng.mobile.clock_demo;

import android.content.Context;
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.util.Log;
import android.view.View;

import java.util.Calendar;

/**
 * Created by gaofeng on 15-8-29.
 */
public class ClockView extends View {




    public ClockView(Context context) {
        super(context);
        ringHourBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ring);
        ringMinBitmap  = BitmapFactory.decodeResource(getResources(),R.drawable.ring_min);
        syncTime();
        setSchedualTime(0);

    }

    public ClockView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    //半径和圆中心
    private static final float Radius = 200;
    private static final float CenterX = 250;
    private static final float CenterY = 250;

    private float secondsDegree = 0;
    private float minDegree = 0;
    private float hourDegree = 0;

    //定时
    private float setHourDegree;
    private float setMinDegree;
    private boolean setSchedual;
    private Bitmap ringHourBitmap;
    private Bitmap ringMinBitmap;
    private int bitmapWidth = 30,bitmapHeight = 30;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        try {// 秒表进度
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        setBackgroundColor(Color.GREEN);
        drawCircle(canvas);
        drawClockPoint(canvas);
        drawIndicator(canvas);
        calc();
        drawSchedual(canvas);
        invalidate();
    }

    private void drawSchedual(Canvas canvas) {
        if (setSchedual) {
            Paint p = new Paint();

            //找到小时的坐标
            float rad = (float )Math.toRadians(setHourDegree);
            float x = (float) (Radius * Math.sin(rad)) ;
            float y = (float) (Radius * Math.cos(rad));


            float vx = CenterX + x;
            float vy = CenterY - y;
            //比较笨的方法解决 图片绘制在圆内。绘制都是从手机左上角开始的
            if (setHourDegree > 0 && setHourDegree <= 90) {
                vx = vx - bitmapWidth;
            }
            if (setHourDegree > 90 && setHourDegree < 180) {
                vx = vx - bitmapWidth;
                vy = vy - bitmapWidth;
            }
            if (setHourDegree > 180 && setHourDegree < 270) {
                vy = vy - bitmapWidth;
            }

            Log.d("","Range x:" + vx + " y:" + vy);
            canvas.drawBitmap(ringHourBitmap,vx ,vy ,p);

            //找到分钟的坐标
            rad = (float )Math.toRadians(setMinDegree);
            x = (float) (Radius * Math.sin(rad)) ;
            y = (float) (Radius * Math.cos(rad))  ;
             vx = CenterX + x;
             vy = CenterY - y;

            if (setMinDegree > 0 && setMinDegree <= 90) {
                vx = vx - bitmapWidth;
            }
            if (setMinDegree > 90 && setMinDegree < 180) {
                vx = vx - bitmapWidth;
                vy = vy - bitmapWidth;
            }
            if (setMinDegree > 180 && setMinDegree < 270) {
                vy = vy - bitmapWidth;
            }

            canvas.drawBitmap(ringMinBitmap,vx,vy ,p);

            p = null;


        }
    }




    private void calc() {
        secondsDegree = secondsDegree + 6;
        if (secondsDegree >=360) { //一圈为一分钟
            secondsDegree = 0;
            minDegree = minDegree + 6;
        }
        if (minDegree >= 360) { //一圈为一个小时
            minDegree = 0;
            hourDegree = hourDegree + 6;
        }
        if (hourDegree >= 360) { //一圈还是从0度开始
            hourDegree = 0;
        }
    }

    //画圆
    private void drawCircle(Canvas canvas) {

        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(2);
        canvas.drawCircle(CenterX,CenterY,Radius,paint);

        Paint paint2 = new Paint();
        paint2.setColor(Color.YELLOW);
        paint2.setStrokeWidth(15f);
        canvas.drawPoint(CenterX,CenterY,paint2);

    }

    private void drawClockPoint(Canvas canvas) {
        Paint paint = new Paint();
        paint.setColor(Color.YELLOW);
        paint.setStrokeWidth(10f);
        //画出闹钟上面的刻度值,一圈一共12个点, 360度
        for (float degree = 0; degree <= 330;degree = degree + 30) {
            //数学公式 找圆上面的点坐标
            float rad = (float )Math.toRadians(degree);//转换为度
            float x = (float) (Radius * Math.sin(rad));
            float y = (float) (Radius * Math.cos(rad));
            canvas.drawPoint(x + CenterX, CenterY - y,paint);
        }
    }

    //画指针,转的慢的指针越厚,默认都从0开始转
    private void drawIndicator(Canvas canvas) {
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(3f);
        //秒针
        _drawLine(canvas,secondsDegree,paint);

        //分针
        paint.setColor(Color.DKGRAY);
        paint.setStrokeWidth(6f);
        _drawLine(canvas,minDegree,paint);


        //时针
        paint.setColor(Color.WHITE);
        paint.setStrokeWidth(12f);
        _drawLine(canvas,hourDegree,paint);
    }


    private void _drawLine(Canvas canvas,float degree,Paint paint) {
        float rad = (float )Math.toRadians(degree);//转换为度
        float x = (float) (Radius * Math.sin(rad));
        float y = (float) (Radius * Math.cos(rad));
        canvas.drawLine(CenterX, CenterY, x + CenterX, CenterY - y, paint);
    }

    public void setSchedualTime(long time) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(time);
        //演示一下
        int hour     = 14;
        int min      = 35;
        if (hour > 12) { //是24小时类型的
            hour = hour - 12;
        }
        //计算和前面一样
        setHourDegree = hour * 30;
        setMinDegree  = min * 6;
        setSchedual = true;
    }


    //和手机时间同步一下
    public void syncTime() {
        Calendar cal = Calendar.getInstance();
        int hour     = cal.get(Calendar.HOUR_OF_DAY);
        int min      = cal.get(Calendar.MINUTE);
        int second   = cal.get(Calendar.SECOND);
        Log.d("","Time Now Hour:" + hour + " Min:" + min + " second:" + second);

        if (hour > 12) { //是24小时类型的
            hour = hour - 12;
        }
        //计算弧度 每个步伐都是 60/360 = 6度,Hour 12/360 度
        hourDegree = hour * 30;
        minDegree  = min * 6;
        secondsDegree = second * 6;
    }


}

总结
- 没有给钟表绘制数字,这个只是画文本比较简单
- 判断定时图片是否在圆内,做的比较简单没有花太多时间去找方法
- 如果要实现能拖分时指针的 需要扩展ViewGroup

版权声明:本文为博主原创文章,未经博主允许不得转载。

安卓小项目之自定义闹钟

近期我正在做一个安卓闹钟的项目,在这个项目中我真可谓是历尽千辛万苦啊,平均每天研究这个程序真的可以研究10个小时左右啊,真的是让我头疼死了。直至现在,我已经可以用好多种方法来实现这个闹钟了,然后如果大...
  • Lin_Sir6
  • Lin_Sir6
  • 2015年12月10日 00:53
  • 2013

Android自定义闹钟

Android闹钟alarmManager+PendingIntent
  • qq_37530633
  • qq_37530633
  • 2017年02月23日 19:58
  • 176

Android学习阶段总结:自己做一个闹钟能学到什么?

初学Android,总是有很多问题,然而视频教程完整的看了,竟仍觉无从下手。面对许多控件,简简单单的测试各项功能,这就是我干了将近半个月的事情。然后我就跟着一个帖子做了个闹钟。这一做,面对几乎现成的代...
  • baidu_26680163
  • baidu_26680163
  • 2015年04月18日 23:15
  • 535

Android之自定义View以及画一个时钟

概述:当Android自带的View满足不了开发者时,自定义View就发挥了很好的作用。 建立一个自定义View,需要继承于View类,并且实现其中的至少一个构造函数和两个方法:onMeasure(...
  • NiZhuanXingHeIT
  • NiZhuanXingHeIT
  • 2015年09月16日 20:42
  • 2677

Android闹钟设置的解决方案

主要问题 API19开始AlarmManager的机制修改。应用程序被Kill掉后,设置的闹钟不响。6.0以上进入Doze模式会使JobScheduler停止工作。手机设置重启后,闹钟失效问题。...
  • chuyouyinghe
  • chuyouyinghe
  • 2016年09月26日 17:08
  • 1212

个人应用调用Android系统闹钟

package com.lsd.CallSystemClock; import java.util.ArrayList; import java.util.List; import android...
  • wenbitianxiafeng
  • wenbitianxiafeng
  • 2014年03月06日 14:21
  • 2706

仿网上一款android闹钟的总结

一周前决定写一款自己独立开发的android小程序,从事开发以来,工作中的大多数时间浪费在了虚无的状态之中,带我的大姐给我讲了很多开发的道理,所以我决定辞职离开了,老板不知道如何锻炼新人,不明白学习应...
  • bianfu2008zhi
  • bianfu2008zhi
  • 2012年03月25日 22:53
  • 673

Android闹钟拓展版【安卓闹钟可换壁纸版】

经过写上篇文章Android闹钟最终版【android源码闹钟解析】 .发现有一些留邮箱的,但凡留邮箱的,我就发源码过去了,不错,基本上收到邮箱的都留言感谢了,这样我的成就感就多一点,也能有更多留邮箱...
  • wdaming1986
  • wdaming1986
  • 2012年04月19日 23:04
  • 9184

Android之实现简单小闹钟

AlarmManager介绍   AlarmManager这个类提供对系统闹钟服务的访问接口。   你可以为你的应用设定一个在未来某个时间唤醒的功能。   当闹钟响起,实际上是系统发出了为这个闹...
  • d_shadow
  • d_shadow
  • 2017年02月15日 00:30
  • 1386

Android AlarmManager加入与取消闹钟提醒, Notification不显示的问题

关于日程提醒,用Android系统的AlarmManager,将提醒时间加入系统闹钟并同广播关联,在闹钟到点提醒时,触发广播,然后弹出通知栏通知日程,以下为设置闹钟的代码 private void ...
  • androidforwell
  • androidforwell
  • 2016年12月16日 18:47
  • 4283
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android自定义View绘制闹钟
举报原因:
原因补充:

(最多只允许输入30个字)