android 自定义时钟控件
不点
阅读:751
2021-04-01 10:10:49
评论:0
效果截图:
自定义时钟组件源代码:
package com.sky_dreaming.analogic_clock.view;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.format.Time;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews.RemoteView;
import java.io.InputStream;
import java.util.TimeZone;
import com.sky_dreaming.analogic_clock.R;
@RemoteView
public class AnalogClock extends View {
//时间
private Time mCalendar;
//时钟图片
private Bitmap mDial;
//设置图片
private BitmapDrawable mDialDrawable;
//时
private BitmapDrawable mHourHandDrawable;
//分
private BitmapDrawable mMinuteHandDrawable;
//秒
private BitmapDrawable mSecondHandDrawable;
//时钟宽度
private int mDialWidth;
//时钟高度
private int mDialHeight;
//是否点击
private boolean mAttached = false;
//现在时间--时
private float mHours;
//现在时间---分
private float mMinutes;
//现在时间--秒
private float mSeconds;
//现在时间字符串
private String time_zone;
public String getTime_zone() {
return time_zone;
}
public void setTime_zone(String timeZone) {
time_zone = timeZone;
}
/**
*时间是否更改
*/
private boolean mChanged;
/**
*主线程
*/
private Handler loopHandler = new Handler();
/**
*是否运行
*/
private boolean isRun = false;
/**
* 主线程处理(时间)
*/
private void run()
{
/**
*时间更改线程
*/
loopHandler.post(tickRunnable);
}
private Runnable tickRunnable = new Runnable() {
public void run() {
/**
* 方法待定
*/
postInvalidate();
/**
* 10秒之后放入主线程之中
*/
loopHandler.postDelayed(tickRunnable, 1000);
}
};
/**
* 相关构造方法
*/
public AnalogClock(Context context) {
this(context, null);
}
public AnalogClock(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AnalogClock(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
/**
* 现在时间实例化
*/
mCalendar = new Time();
time_zone = mCalendar.timezone;
Resources r = this.getContext().getResources();
InputStream is =null;
/**
* 资源图片读取
*/
is = r.openRawResource(R.drawable.clock);
mDialDrawable = new BitmapDrawable(is);
mDial = mDialDrawable.getBitmap();
is = r.openRawResource(R.drawable.hands);
mHourHandDrawable = new BitmapDrawable(is);
is = r.openRawResource(R.drawable.hands);
mMinuteHandDrawable = new BitmapDrawable(is);
is = r.openRawResource(R.drawable.hands);
mSecondHandDrawable = new BitmapDrawable(is);
/**
* 图片大小获取
*/
mDialWidth = mDialDrawable.getIntrinsicWidth();
mDialHeight = mDialDrawable.getIntrinsicHeight();
}
//view 相关覆写方法
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!mAttached) {
mAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getContext().registerReceiver(mIntentReceiver, filter, null, loopHandler);
}
}
//view 相关覆写方法
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAttached) {
getContext().unregisterReceiver(mIntentReceiver);
mAttached = false;
}
}
//view 相关覆写方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
float hScale = 1.0f;
float vScale = 1.0f;
if (widthMode != MeasureSpec.UNSPECIFIED && widthSize < mDialWidth) {
hScale = (float) widthSize / (float) mDialWidth;
}
if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mDialHeight) {
vScale = (float )heightSize / (float) mDialHeight;
}
float scale = Math.min(hScale, vScale);
setMeasuredDimension(resolveSize((int) (mDialWidth * scale), widthMeasureSpec),
resolveSize((int) (mDialHeight * scale), heightMeasureSpec));
}
//view 相关覆写方法
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mChanged = true;
}
//view 相关覆写方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(!isRun)
{
run();
isRun = true;
return;
}
//时间更改函数
onTimeChanged();
boolean changed = mChanged;
if (changed) {
mChanged = false;
}
int availableWidth = mDial.getWidth();
int availableHeight = mDial.getHeight();
int x = availableWidth / 2;
int y = availableHeight / 2;
final Drawable dial = mDialDrawable;
int w = dial.getIntrinsicWidth();
int h = dial.getIntrinsicHeight();
boolean scaled = false;
if (availableWidth < w || availableHeight < h) {
scaled = true;
float scale = Math.min((float) availableWidth / (float) w,
(float) availableHeight / (float) h);
canvas.save();
canvas.scale(scale, scale, x, y);
}
if (changed) {
dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
dial.draw(canvas);
canvas.save();
canvas.rotate(mHours / 12.0f * 360.0f, x, y);
final Drawable hourHand = mHourHandDrawable;
if (changed) {
w = hourHand.getIntrinsicWidth();
h = hourHand.getIntrinsicHeight();
hourHand.setBounds(x - (w / 2), y - (h * 2 / 3), x + (w / 2), y + (h / 3));
}
hourHand.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(mMinutes / 60.0f * 360.0f, x, y);
final Drawable minuteHand = mMinuteHandDrawable;
if (changed) {
w = minuteHand.getIntrinsicWidth();
h = minuteHand.getIntrinsicHeight();
minuteHand.setBounds(x - (w / 2), y - (h * 4 / 5), x + (w / 2), y + (h / 5));
}
minuteHand.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(mSeconds / 60.0f * 360.0f, x, y);
final Drawable scendHand = mSecondHandDrawable;
if (changed) {
w = scendHand.getIntrinsicWidth();
h = scendHand.getIntrinsicHeight();
scendHand.setBounds(x - (w / 2), y - h, x + (w / 2), y);
}
scendHand.draw(canvas);
canvas.restore();
if (scaled) {
canvas.restore();
}
}
//自定义时间更改函数
private void onTimeChanged() {
mCalendar.setToNow();
int hour = mCalendar.hour;
int minute = mCalendar.minute;
int second = mCalendar.second;
mSeconds = second;
mMinutes = minute + second / 60.0f;
mHours = hour + mMinutes / 60.0f;
mChanged = true;
}
//自定义广播
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String tz = "";
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
tz = intent.getStringExtra("time-zone");
mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
time_zone = mCalendar.timezone;
}
Log.i("********************",tz);
onTimeChanged();
invalidate();
}
};
}
自定义时钟控件下载地址:http://download.csdn.net/detail/zhouzhiwengang/6366727
声明
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。