几天前,又温习了一遍Android群英传,看到了仪表盘这个案例,我看了就想把他再加工一下,给做成一个可以转动的钟表,现在来分析一下,主要界面还是书上的代码,主要的改进就是对指针坐标的计算,这里记录一下,毕竟自己也是刚开始自己写自定义控件。
--------------------------------------------------------------------------------------------------------------------------------
直接上源代码,都有注释很好理解。
package com.aijie.viewandgroupapp.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * Created by Administrator on 2016/7/8 0008. * 实现一个钟表的View */ public class RoundClockView extends View { private Context mContext; /** * 画笔 */ private Paint mPaint; /** * 控件的宽 */ private int mWidth; /** * x方向的圆心坐标 */ private int center; /** * 钟表的半径 */ private int radio; /** * 圆环的宽 */ private int strokeWidth = 8; /** * 当前小时 */ private int mCurrentHour; /** * 当前分钟 */ private int mCurrentMinute; /** * 当前秒 */ private int mCurrentSecond; /** * 时针的长度 */ private int hourLineLen; /** * 分针的长度 */ private int minuteLineLen; /** * 秒针的长度 */ private int secondLineLen; /** * 时针扫过的角度 */ private int hourDegree; /** * 分针扫过的角度 */ private int minuteDegree; /** * 秒针扫过的角度 */ private int secondDegree; /** * 时针,分针,秒针的终点坐标 */ private int hourEndX; private int hourEndY; private int minuteEndX; private int minuteEndY; private int secondEndX; private int secondEndY; public RoundClockView(Context context) { this(context, null); } public RoundClockView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundClockView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 抗锯齿 mPaint.setColor(Color.RED); new Thread(new Runnable() { @Override public void run() { Timer timer = new Timer(); TimerTask task = new TimerTask() { @Override public void run() { postInvalidate(); } }; timer.schedule(task, 1000, 1000); } }).start(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mWidth = getWidth(); center = mWidth / 2; // 圆心 x radio = center - strokeWidth / 2; // 半径 hourLineLen = radio - 200; // 时针长度 minuteLineLen = radio - 120; // 分针长度 secondLineLen = radio - 80; // 秒针长度 // 画一个中心 canvas.drawCircle(center, center, 10, mPaint); // 设置为空心 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(strokeWidth); // 画圆 canvas.drawCircle(center, center, radio, mPaint); // 画刻度 for (int i = 0; i < 60; i++) { if (i % 5 == 0) { // 整点 canvas.drawLine(center, 0, center, 40, mPaint); // 画数字 mPaint.setTextSize(40); float textSize = mPaint.getTextSize(); String clockText = i / 5 == 0 ? "12" : i / 5 + ""; canvas.drawText(clockText, center - textSize / 2, 80, mPaint); } else { // 非整点 canvas.drawLine(center, 0, center, 20, mPaint); } // 旋转画布 canvas.rotate(6, center, center); } // 获取当前时间 initCurrentTime(); // 画秒针 canvas.drawLine(center, center, secondEndX, secondEndY, mPaint); // 画分针 canvas.drawLine(center, center, minuteEndX, minuteEndY, mPaint); // 画时针 mPaint.setStrokeWidth(15); canvas.drawLine(center, center, hourEndX, hourEndY, mPaint); } /** * 初始化当前时间,计算时针分针的终点坐标 */ private void initCurrentTime() { // 获取当前时间 SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss"); String time = format.format(new Date()); String result[] = time.split(":"); mCurrentHour = Integer.parseInt(result[0]); mCurrentMinute = Integer.parseInt(result[1]); mCurrentSecond = Integer.parseInt(result[2]); mCurrentHour = mCurrentHour >= 12 ? mCurrentHour - 12 : mCurrentHour; mCurrentMinute = mCurrentHour == 60 ? 0 : mCurrentMinute; mCurrentSecond = mCurrentSecond == 60 ? 0 : mCurrentSecond; // 秒针角度 secondDegree = mCurrentSecond * 6; // 分针角度 minuteDegree = mCurrentMinute * 6; // 时针角度(还要考虑分针角度) hourDegree = mCurrentHour * 30 + Double.valueOf(30 * (minuteDegree*1.0 / 360)).intValue(); // 换算成弧度 double hourDeg = Math.PI * hourDegree / 180; double minuteDeg = Math.PI * minuteDegree / 180; double secondDeg = Math.PI * secondDegree / 180; // 计算指针终点坐标 hourEndX = center + Double.valueOf(hourLineLen * Math.sin(hourDeg)).intValue(); hourEndY = center - Double.valueOf(hourLineLen * Math.cos(hourDeg)).intValue(); minuteEndX = center + Double.valueOf(minuteLineLen * Math.sin(minuteDeg)).intValue(); minuteEndY = center - Double.valueOf(minuteLineLen * Math.cos(minuteDeg)).intValue(); secondEndX = center + Double.valueOf(secondLineLen * Math.sin(secondDeg)).intValue(); secondEndY = center - Double.valueOf(secondLineLen * Math.cos(secondDeg)).intValue(); } /** * 设置当前时间 * * @param hour 小时 * @param minute 分钟 */ public void setCurrentTime(int hour, int minute) { this.mCurrentHour = hour; this.mCurrentMinute = minute; postInvalidate(); } }