您的位置:首页 > 移动开发 > Android开发

Android自定义View绘制闹钟

2015-08-29 17:16 585 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: