翻页时钟java代码_Android编程基于自定义控件实现时钟功能的方法

本文介绍了如何在Android中使用自定义控件实现一个动态翻页时钟。通过创建ClockView类,设置画笔并利用Canvas绘制圆、刻度、数字和指针,结合Handler实现每秒更新并重绘,达到时钟动画效果。在Activity的onResume和onStop方法中控制时钟的启动和停止。
摘要由CSDN通过智能技术生成

本文实例讲述了Android编程基于自定义控件实现时钟功能的方法。分享给大家供大家参考,具体如下:

在学习安卓群英传自定义控件章节的时候,有一个例子是绘制时钟,在实现了书上的例子后就想看这个时钟能不能动起来。

这里选择延迟一秒发送消息重绘view来实现的动画,对外提供了开启时钟,关闭时钟的方法,当activity执行onResume方法的时候,执行startClock()方法,当移除view或activity执行onStop方法的时候可以执行stopClock()方法。

首先根据view的宽高来确定圆心的位置,并画出一个圆。再通过view高度的一半减去圆的半径,确定刻度的起始位置,选择刻度的长度并绘制出来。然后再刻度下方绘制出数字。最终将画布进行旋转,时钟总共有60个刻度,循环旋转,每次旋转6度即可。

最后是绘制指针,通过计算算出指针对应每个刻度的X,Y坐标并绘制直线。

c81bc50f6bfd1d43c5d98585edff3803.gif

代码实现

自定义控件的代码(ClockView.java):

package com.example.clock;

import java.util.Calendar;

import java.util.Date;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.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;

private double hour;

private Handler handler = new Handler(Looper.getMainLooper()) {

@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) {

super.onMeasure(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) {

super.onDraw(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.drawLine(hourStartPoint.getX(), hourStartPoint.getY(),

hourEndPoint.getX(), hourEndPoint.getY(), circlePaint);

// 画数字,需在时针刻度末端加30

canvas.drawText(clockNumber,

circleX - numberPaint.measureText(clockNumber) / 2,

hourEndPoint.getY() + 30, numberPaint);

} else {

// 画分针刻度

canvas.drawLine(startPoint2.getX(), startPoint2.getY(),

endPoint2.getX(), endPoint2.getY(), circlePaint);

}

// 画布旋转6度

canvas.rotate(360 / 60, circleX, circleY);

}

}

/**

* 画指针 X点坐标 cos(弧度)*r Y点坐标 sin(弧度)*r toRadians将角度转成弧度

* 安卓坐标系与数学坐标系不同的地方是X轴是相反的,所以为了调整方向,需要将角度+270度

*

* @param canvas

*/

private void drawPointer(Canvas canvas) {

canvas.translate(circleX, circleY);

float hourX = (float) Math.cos(Math.toRadians(hour * 30 + 270))

* circleRadius * 0.5f;

float hourY = (float) Math.sin(Math.toRadians(hour * 30 + 270))

* circleRadius * 0.5f;

float minuteX = (float) Math.cos(Math.toRadians(minute * 6 + 270))

* circleRadius * 0.8f;

float minuteY = (float) Math.sin(Math.toRadians(minute * 6 + 270))

* circleRadius * 0.8f;

float secondX = (float) Math.cos(Math.toRadians(second * 6 + 270))

* circleRadius * 0.8f;

float secondY = (float) Math.sin(Math.toRadians(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);

// 一秒重绘一次

handler.sendEmptyMessageDelayed(0, 1000);

}

public void startClock() {

setTimes();

invalidate();

}

private void setTimes() {

Date date = new Date();

Calendar calendar = Calendar.getInstance();

calendar.setTime(date);

second = getTimes(date, Calendar.SECOND);

minute = getTimes(date, Calendar.MINUTE);

hour = getTimes(date, Calendar.HOUR) + minute / 12 * 0.2;

}

private int getTimes(Date date, int calendarField) {

Calendar calendar = Calendar.getInstance();

calendar.setTime(date);

return calendar.get(calendarField);

}

public void stopClock() {

handler.removeMessages(0);

}

}

Point.java:

package com.example.clock;

public class Point {

private float x;

private float y;

public Point(float x, float y) {

this.x = x;

this.y = y;

}

public float getX() {

return x;

}

public void setX(float x) {

this.x = x;

}

public float getY() {

return y;

}

public void setY(float y) {

this.y = y;

}

}

Acitivity(ClockActivity.java):

package com.example.clock;

import android.app.Activity;

import android.os.Bundle;

public class ClockActivity extends Activity {

/** Called when the activity is first created. */

private ClockView clockView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

clockView = (ClockView) findViewById(R.id.clock);

}

@Override

protected void onResume() {

super.onResume();

clockView.startClock();

}

@Override

protected void onStop() {

super.onStop();

clockView.stopClock();

}

}

xml布局(main.xml):

android:orientation="vertical"

android:layout_width="match_parent"

android:gravity="center"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:id="@+id/clock"

android:layout_height="match_parent" />

希望本文所述对大家Android程序设计有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值