Android自定义View绘制闹钟

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

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

时间: 2024-10-18 06:47:02

Android自定义View绘制闹钟的相关文章

android自定义View绘制圆形头像与椭圆头像

要实现这两种效果,需要自定义View,并且有两种实现方式. 第一种: public class BitmapShaders extends View { private  BitmapShader bitmapShader = null; private Bitmap bitmap = null; private Paint paint = null; private ShapeDrawable shapeDrawable = null; private int BitmapWidth  = 0

Android自定义View【实战教程】5??---Canvas详解及代码绘制安卓机器人

友情链接: Canvas API Android自定义View[实战教程]3??--Paint类.Path类以及PathEffect类详解 神马是Canvas 基本概念 Canvas:可以理解为是一个为我们提供了各种工具的画布,我们可以在上面尽情的绘制(旋转,平移,缩放等等).可以理解为系统分配给我们一个一个内存空间,然后提供了一些对这个内存空间操作的方法(API), 实际存储是在下面的bitmap. 两种画布 这里canvas可以绘制两种类型的画图,分别是view和surfaceView. V

Android自定义view之绘制实用型的柱形图和折线图

概述: 前几天突然需要做两种图表--柱形图.折线图,于是第一反应是先看看网上有没有现成的,结果有是有,但都不是我想要的,而且大多数不是用纯android代码完成,HTML5似乎完成这类工作要容易得多,但是我本人并不会HTML5,只能黯然神伤,掩面流泪,最终只能自己敲代码了. **知识点:**android自定义view.图形图像.Fragment.MVC模式. Demo 界面是模仿红圈营销搭建的 折线图: 代码,注释很详细,直接看代码就行了: public class LineChartView

Android应用自定义View绘制方法手册

背景 这篇迟迟难产的文章算是对2015前半年的一个交代吧,那时候有一哥们要求来一发Android Canvas相关总结,这哥们还打赏了,实在不好意思,可是这事一放就给放忘了,最近群里小伙伴催着说没更新博客,坐等更新啥的,随先有这么一篇Android应用开发超级基础的文章诞生了(因为这种文章最好写哈,就是用熟了就行).不得不说下这么久为何一直没更新博客的原因了,首先遇上了过年,我个人崇尚过节就该放下一切好好陪陪亲人,珍惜在一起的时光:其次今年开年很是蛋疼,不是不顺当就是深深的觉得被坑,所以心情也就

Android 自定义View视图

创建全新的视图将满足我们独特的UI需求. 本文介绍在指南针开发中会用到的罗盘的界面UI,通过继承View类实现的自定义视图,以此来深刻了解自定义视图. 实现效果图: 源代码: 布局文件activity_main(其中CompassView继承View类): <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.

(转)[原] Android 自定义View 密码框 例子

遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 样子 支持的样式 可以通过XML定义影响外边和行为的属性如下 边框圆角值,边框颜色,分割线颜色,边框宽度,密码长度,密码大小,密码颜色 <declare-styleable name="PasswordInputView"> <attr name="border

Android自定义View——圆形进度条式按钮

介绍 今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图. 和普通的圆形进度条类似,只是中间的地方有两个状态表示,未开始,暂停状态.而且他说圆形进度的功能已经实现了.那么我们只需要对中间的两个状态做处理就行了. 先来看看实现的效果图: 上面说了我们只需要处理中间状态的变化就可以了,对于进度的处理直接使用了弘洋文章中实现: http://blog.csdn.net/lmj623565791/article/details/43371299 下面开始具体实现. 具体实

Android自定义View(二、深入解析自定义属性)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51468648 本文出自:[openXu的博客] 目录: 为什么要自定义属性 怎样自定义属性 属性值的类型format 类中获取属性值 Attributeset和TypedArray以及declare-styleable ??在上一篇博客<Android自定义View(一.初体验)>中我们体验了自定义控件的基本流程: 继承View,覆盖构造方法 自定义属性 重写onMeasure方法测量宽

Android 自定义 view(三)&mdash;&mdash; onDraw

前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自定义view的两个比较重要的方法 onDraw(Canvas canvas) ,在探究 onDraw方法之前,我们必须先深入了解两个类Paint和Canvas .   第一:认识Paint 在探究onDraw之前首先必须要认识两个类,这里给出非常不错的两个资料参考网站,我也是从这里得到想要知道的东西,简单的说