前言
前不久在网上看见Android实现的模拟时钟,感觉十分有意思,这里是地址:
?mod=viewthread&tid=58324可惜的是这种方式没有
秒表。笔者突然对其有了兴趣,也想去实现以下自己的模拟时钟。折腾了一阵子总算是弄出来了
现在将实现方式共享出来,大家一些交流。
不多说,先上效果图:
准备工作
首先我们应该准备相关的素材:时钟盘、时针、分针、秒针图片.
时钟盘:
时针:
分针:
秒针:
配置文件,比较简单:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:context=".MainActivity" android:background="@color/bg"> <com.kiritor.mymodelclock.MyQAnalogClock android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>MyQAnalogClock代码:用于构造时钟view以及其刷新显示:
package com.kiritor.mymodelclock; import android.util.AttributeSet; import com.kiritor.mymodelclock.R; import android.content.Context; import android.graphics.*; import android.graphics.drawable.BitmapDrawable; import android.os.Handler; import android.view.View; import java.util.Calendar; import java.util.TimeZone; /** * Created by Kiritor on 13-5-30. */ public class MyQAnalogClock extends View { //时钟盘,分针、秒针、时针对象 Bitmap mBmpDial; Bitmap mBmpHour; Bitmap mBmpMinute; Bitmap mBmpSecond; BitmapDrawable bmdHour; BitmapDrawable bmdMinute; BitmapDrawable bmdSecond; BitmapDrawable bmdDial; Paint mPaint; Handler tickHandler; int mWidth; int mHeigh; int mTempWidth = bmdSecond.getIntrinsicWidth(); int mTempHeigh; int centerX; int centerY; int availableWidth = 100; int availableHeight = 100; private String sTimeZoneString; public MyQAnalogClock(Context context,AttributeSet attr) { this(context,"GMT+8:00"); } public MyQAnalogClock(Context context, String sTime_Zone) { super(context); sTimeZoneString = sTime_Zone; mBmpHour = BitmapFactory.decodeResource(getResources(), R.drawable.shizhen); bmdHour = new BitmapDrawable(mBmpHour); mBmpMinute = BitmapFactory.decodeResource(getResources(), R.drawable.fenzhen); bmdMinute = new BitmapDrawable(mBmpMinute); mBmpSecond = BitmapFactory.decodeResource(getResources(), R.drawable.miaozhen); bmdSecond = new BitmapDrawable(mBmpSecond); mBmpDial = BitmapFactory.decodeResource(getResources(), R.drawable.android_clock_dial); bmdDial = new BitmapDrawable(mBmpDial); mWidth = mBmpDial.getWidth(); mHeigh = mBmpDial.getHeight(); centerX = availableWidth / 2; centerY = availableHeight / 2; mPaint = new Paint(); mPaint.setColor(Color.BLUE); run(); } public void run() { tickHandler = new Handler(); tickHandler.post(tickRunnable); } private Runnable tickRunnable = new Runnable() { public void run() { postInvalidate(); tickHandler.postDelayed(tickRunnable, 1000); } }; protected void onDraw(Canvas canvas) { super.onDraw(canvas); Calendar cal = Calendar.getInstance(TimeZone .getTimeZone(sTimeZoneString)); int hour = cal.get(Calendar.HOUR); int minute = cal.get(Calendar.MINUTE); int second = cal.get(Calendar.SECOND); float hourRotate = hour * 30.0f + minute / 60.0f * 30.0f; float minuteRotate = minute * 6.0f; float secondRotate = second * 6.0f; boolean scaled = false; if (availableWidth < mWidth || availableHeight < mHeigh) { scaled = true; float scale = Math.min((float) availableWidth / (float) mWidth, (float) availableHeight / (float) mHeigh); canvas.save(); canvas.scale(scale, scale, centerX, centerY); } bmdDial.setBounds(centerX - (mWidth / 2), centerY - (mHeigh / 2), centerX + (mWidth / 2), centerY + (mHeigh / 2)); bmdDial.draw(canvas); mTempWidth = bmdHour.getIntrinsicWidth(); mTempHeigh = bmdHour.getIntrinsicHeight(); canvas.save(); canvas.rotate(hourRotate, centerX, centerY); bmdHour.setBounds(centerX - (mTempWidth / 2), centerY - (mTempHeigh / 2), centerX + (mTempWidth / 2), centerY + (mTempHeigh / 2)); bmdHour.draw(canvas); canvas.restore(); mTempWidth = bmdMinute.getIntrinsicWidth(); mTempHeigh = bmdMinute.getIntrinsicHeight(); canvas.save(); canvas.rotate(minuteRotate, centerX, centerY); bmdMinute.setBounds(centerX - (mTempWidth / 2), centerY - (mTempHeigh / 2), centerX + (mTempWidth / 2), centerY + (mTempHeigh / 2)); bmdMinute.draw(canvas); canvas.restore(); mTempWidth = bmdSecond.getIntrinsicWidth(); mTempHeigh = bmdSecond.getIntrinsicHeight(); canvas.rotate(secondRotate, centerX, centerY); bmdSecond.setBounds(centerX - (mTempWidth / 2), centerY - (mTempHeigh / 2), centerX + (mTempWidth / 2), centerY + (mTempHeigh / 2)); bmdSecond.draw(canvas); if (scaled) { canvas.restore(); } } }