翻页时钟java代码_Android编程基于⾃定义控件实现时钟功能
的⽅法
本⽂实例讲述了Android编程基于⾃定义控件实现时钟功能的⽅法。分享给⼤家供⼤家参考,具体如下:
在学习安卓英传⾃定义控件章节的时候,有⼀个例⼦是绘制时钟,在实现了书上的例⼦后就想看这个时钟能不能动起来。
这⾥选择延迟⼀秒发送消息重绘view来实现的动画,对外提供了开启时钟,关闭时钟的⽅法,当activity执⾏onResume⽅法的时候,执⾏startClock()⽅法,当移除view或activity执⾏onStop⽅法的时候可以执⾏stopClock()⽅法。
⾸先根据view的宽⾼来确定圆⼼的位置,并画出⼀个圆。再通过view⾼度的⼀半减去圆的半径,确定刻度的起始位置,选择刻度的长度并绘制出来。然后再刻度下⽅绘制出数字。最终将画布进⾏旋转,时钟总共有60个刻度,循环旋转,每次旋转6度即可。
最后是绘制指针,通过计算算出指针对应每个刻度的X,Y坐标并绘制直线。
代码实现
⾃定义控件的代码(ClockView.java):
ample.clock;
import java.util.Calendar;
import java.util.Date;
t.Context;
aphics.Canvas;
aphics.Color;
aphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
public class ClockView extends View {
private Paint circlePaint, dialPaint, numberPaint;
/
/ view 的宽⾼
private float mWidth, mHeight;
// 圆的半径
private float circleRadius;
// 圆⼼X,Y坐标
private float circleX, circleY;
private int second, minute;
android编程入门指南 pdfprivate double hour;
private Handler handler = new MainLooper()) { @Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
invalidate();
}
}
};
public ClockView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
private void initPaint() {
// 刻盘圆,⼩时刻度,时针和分针的画笔
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.BLACK);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeWidth(10);
// 分钟刻度的画笔
dialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dialPaint.setColor(Color.BLACK);
dialPaint.setStrokeWidth(5);
// 数字的画笔
numberPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
numberPaint.setColor(Color.BLACK);
numberPaint.setStrokeWidth(5);
numberPaint.setTextSize(30);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Measure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
if (mWidth < mHeight) {
// 圆的半径为view的宽度的⼀半再减9,防⽌贴边
circleRadius = mWidth / 2 - 9;
circleX = mWidth / 2;
circleY = mHeight / 2;
} else {
circleRadius = mHeight / 2 - 9;
circleX = mWidth / 2;
circleY = mHeight / 2;
}
}
@Override
protected void onDraw(Canvas canvas) {
setTimes();
drawCirclePoint(canvas);
drawCircle(canvas);
drawDial(canvas);
drawPointer(canvas);
}
/**
* 圆⼼
*
* @param canvas
*/
private void drawCirclePoint(Canvas canvas) {
canvas.drawCircle(circleX, circleY, 5, circlePaint);
}
private void drawCircle(Canvas canvas) {
canvas.drawCircle(circleX, circleY, circleRadius, circlePaint);
}
/**
* 画刻度及时间
*
* @param canvas
*/
private void drawDial(Canvas canvas) {
/
/ 时钟⽤长⼀点的刻度,画笔⽤画圆的画笔
Point hourStartPoint = new Point(circleX, circleY - circleRadius);
Point hourEndPoint = new Point(circleX, circleY - circleRadius + 40);
// 分钟的刻度要稍微短⼀些,画笔⽤画圆的画笔
Point startPoint2 = new Point(circleX, circleY - circleRadius);
Point endPoint2 = new Point(circleX, circleY - circleRadius + 10);
// 开始画刻度和数字,总共60个刻度,12个时钟刻度,被5整除画⼀个时钟刻度,被其余的为分针刻度String clockNumber;
for (int i = 0; i < 60; i++) {
if (i % 5 == 0) {
if (i == 0) {
clockNumber = "12";
} else {
clockNumber = String.valueOf(i / 5);
}
// 时针刻度
canvas.X(), Y(),
// 画数字,需在时针刻度末端加30
canvas.drawText(clockNumber,
circleX - asureText(clockNumber) / 2,
} else {
/
/ 画分针刻度
canvas.X(), Y(),
}
// 画布旋转6度
}
}
/**
* 画指针 X点坐标 cos(弧度)*r Y点坐标 sin(弧度)*r toRadians将⾓度转成弧度
* 安卓坐标系与数学坐标系不同的地⽅是X轴是相反的,所以为了调整⽅向,需要将⾓度+270度*
* @param canvas
*/
private void drawPointer(Canvas canvas) {
float hourX = (float) Radians(hour * 30 + 270))
* circleRadius * 0.5f;
float hourY = (float) Math.Radians(hour * 30 + 270))
* circleRadius * 0.5f;
float minuteX = (float) Radians(minute * 6 + 270))
* circleRadius * 0.8f;
float minuteY = (float) Math.Radians(minute * 6 + 270))
* circleRadius * 0.8f;
float secondX = (float) Radians(second * 6 + 270))
* circleRadius * 0.8f;
float secondY = (float) Math.Radians(second * 6 + 270))
* circleRadius * 0.8f;
canvas.drawLine(0, 0, hourX, hourY, circlePaint);
canvas.drawLine(0, 0, minuteX, minuteY, circlePaint);
canvas.drawLine(0, 0, secondX, secondY, dialPaint);
// ⼀秒重绘⼀次