Back to project page 24hAnalogWidget.
The source code is released under:
GNU General Public License
If you think the Android project 24hAnalogWidget listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package info.staticfree.android.twentyfourhour; /*//from ww w . j a v a 2 s . c om * Copyright (C) 2011-2014 Steve Pomeroy <steve@staticfree.info> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Some portions Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import java.util.ArrayList; import java.util.Calendar; import java.util.TimeZone; import info.staticfree.android.twentyfourhour.lib.R; import info.staticfree.android.twentyfourhour.overlay.DialOverlay; import info.staticfree.android.twentyfourhour.overlay.HandsOverlay; /** * A widget that displays the time as a 12-at-the-top 24 hour analog clock. By * default, it will show the current time in the current timezone. The displayed * time can be set using {@link #setTime(long)} and and * {@link #setTimezone(TimeZone)}. * * @author <a href="mailto:steve@staticfree.info">Steve Pomeroy</a> */ public class Analog24HClock extends View { private Calendar mCalendar; private Drawable mFace; private int mDialWidth; private int mDialHeight; private int mBottom; private int mTop; private int mLeft; private int mRight; private boolean mSizeChanged; private HandsOverlay mHandsOverlay; private final ArrayList<DialOverlay> mDialOverlay = new ArrayList<DialOverlay>(); public Analog24HClock(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } public Analog24HClock(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); } public Analog24HClock(Context context) { super(context); init(context, null, 0); } private void init(Context context, AttributeSet attributeSet, int defStyle) { final TypedArray attrs = context.obtainStyledAttributes(attributeSet, R.styleable.Analog24HClock, defStyle, 0); Drawable face = attrs.getDrawable(R.styleable.Analog24HClock_face); if (face != null) { setFace(face); } else { setFace(R.drawable.clock_face); } Drawable hourHand = attrs.getDrawable(R.styleable.Analog24HClock_hour_hand); if (hourHand == null) { hourHand = context.getResources().getDrawable(R.drawable.hour_hand); } Drawable minuteHand = attrs.getDrawable(R.styleable.Analog24HClock_minute_hand); if (minuteHand == null) { minuteHand = context.getResources().getDrawable(R.drawable.minute_hand); } mCalendar = Calendar.getInstance(); mHandsOverlay = new HandsOverlay(hourHand, minuteHand); } public void setFace(int drawableRes) { final Resources r = getResources(); setFace(r.getDrawable(drawableRes)); } public void setFace(Drawable face) { mFace = face; mSizeChanged = true; mDialHeight = mFace.getIntrinsicHeight(); mDialWidth = mFace.getIntrinsicWidth(); invalidate(); } /** * Sets the currently displayed time in {@link System#currentTimeMillis()} * time. * * @param time the time to display on the clock */ public void setTime(long time) { mCalendar.setTimeInMillis(time); invalidate(); } /** * Sets the currently displayed time. * * @param calendar The time to display on the clock */ public void setTime(Calendar calendar) { mCalendar = calendar; invalidate(); } /** * When set, the minute hand will move slightly based on the current number * of seconds. If false, the minute hand will snap to the minute ticks. * Note: there is no second hand, this only affects the minute hand. * * @param showSeconds */ public void setShowSeconds(boolean showSeconds) { mHandsOverlay.setShowSeconds(showSeconds); } /** * Sets the timezone to use when displaying the time. * * @param timezone */ public void setTimezone(TimeZone timezone) { mCalendar = Calendar.getInstance(timezone); } public void setHandsOverlay(HandsOverlay handsOverlay) { mHandsOverlay = handsOverlay; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mSizeChanged = true; } // some parts from AnalogClock.java @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); final boolean sizeChanged = mSizeChanged; mSizeChanged = false; final int availW = mRight - mLeft; final int availH = mBottom - mTop; final int cX = availW / 2; final int cY = availH / 2; final int w = mDialWidth; final int h = mDialHeight; boolean scaled = false; if (availW < w || availH < h) { scaled = true; final float scale = Math.min((float) availW / (float) w, (float) availH / (float) h); canvas.save(); canvas.scale(scale, scale, cX, cY); } if (sizeChanged) { mFace.setBounds(cX - (w / 2), cY - (h / 2), cX + (w / 2), cY + (h / 2)); } mFace.draw(canvas); for (final DialOverlay overlay : mDialOverlay) { overlay.onDraw(canvas, cX, cY, w, h, mCalendar, sizeChanged); } mHandsOverlay.onDraw(canvas, cX, cY, w, h, mCalendar, sizeChanged); if (scaled) { canvas.restore(); } } // from AnalogClock.java @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int widthSize = MeasureSpec.getSize(widthMeasureSpec); final int heightMode = MeasureSpec.getMode(heightMeasureSpec); final 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; } final float scale = Math.min(hScale, vScale); setMeasuredDimension( getDefaultSize((int) (mDialWidth * scale), widthMeasureSpec), getDefaultSize((int) (mDialHeight * scale), heightMeasureSpec)); } @Override protected int getSuggestedMinimumHeight() { return mDialHeight; } @Override protected int getSuggestedMinimumWidth() { return mDialWidth; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // because we don't have access to the actual protected fields mRight = right; mLeft = left; mTop = top; mBottom = bottom; } public void addDialOverlay(DialOverlay dialOverlay) { mDialOverlay.add(dialOverlay); } public void removeDialOverlay(DialOverlay dialOverlay) { mDialOverlay.remove(dialOverlay); } public void clearDialOverlays() { mDialOverlay.clear(); } }