I work at world analog clock I used android analog clock, it's work at activity but I can't use it at widget,I tired googled it is there any one have idea ?
You can use the following widget classes in Home Screen Widget:
* AnalogClock
* Button
* Chronometer
* ImageButton
* ImageView
* ProgressBar
* TextView
Descendants of these classes are not supported
see an example how we use an AnalogClock widget in Home Screen widget here
You have to create your own widget based on ImageView and create background service to create bitmaps and periodically push them to widget.
/**
*
* This widget display an analogic clock with two hands for hours and
*
* minutes.
*/
#RemoteView
public class AnalogClock2 extends View {
public AnalogClock2(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
private Time mCalendar;
private Drawable mHourHand;
private Drawable mMinuteHand;
private Drawable mSecondHand;
private Drawable mDial;
private int mDialWidth;
private int mDialHeight;
private boolean mAttached;
private final Handler mHandler = new Handler();
private float mMinutes;
private float mHour;
private boolean mChanged;
Context mContext;
public static String mtimezone="Asia/Calcutta";
public AnalogClock2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AnalogClock2(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
Resources r = context.getResources();
// TypedArray a =
// context.obtainStyledAttributes(
// attrs, R.styleable.AnalogClock, defStyle, 0);
mContext = context;
// mDial =
// a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
// if (mDial == null) {
mDial = r.getDrawable(R.drawable.widgetdial);
// }
// mHourHand =
// a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour);
// if (mHourHand == null) {
mHourHand = r.getDrawable(R.drawable.widgethour);
// }
// mMinuteHand =
// a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);
// if (mMinuteHand == null) {
mMinuteHand = r.getDrawable(R.drawable.widgetminute);
mSecondHand = r.getDrawable(R.drawable.widgetminute);
// }
mCalendar = new Time();
mDialWidth = mDial.getIntrinsicWidth();
mDialHeight = mDial.getIntrinsicHeight();
}
public static void timezone(String timezone){
mtimezone=timezone;
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!mAttached) {
mAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
}
// NOTE: It's safe to do these after registering the receiver since the
// receiver always runs
// in the main thread, therefore the receiver can't run before this
// method returns.
// The time zone may have changed while the receiver wasn't registered,
// so update the Time
//mCalendar = new Time();
mCalendar = new Time(mtimezone);
// Make sure we update to the current time
onTimeChanged();
counter.start();
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAttached) {
counter.cancel();
getContext().unregisterReceiver(mIntentReceiver);
mAttached = false;
}
}
#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;
}
System.out.println("***********************HAI****************");
float scale = Math.min(hScale, vScale);
setMeasuredDimension(resolveSize((int) (mDialWidth * scale), widthMeasureSpec),
resolveSize((int) (mDialHeight * scale), heightMeasureSpec));
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mChanged = true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// // here changes on every tick//////
// / ////
// / //
// //////
// // ///
// //
boolean changed = mChanged;
if (changed) {
mChanged = false;
}
boolean seconds = mSeconds;
if (seconds) {
mSeconds = false;
}
int availableWidth = 100;
int availableHeight = 200;
int x = availableWidth / 2;
int y = availableHeight / 2;
final Drawable dial = mDial;
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(mHour / 12.0f * 360.0f, x, y);
final Drawable hourHand = mHourHand;
if (changed) {
w = hourHand.getIntrinsicWidth();
h = hourHand.getIntrinsicHeight();
hourHand.setBounds(x - (w / 2), y - (h / 3), x + (w / 2), y + (h / 3));
}
hourHand.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(mMinutes / 60.0f * 360.0f, x, y);
// canvas.rotate(mSecond, x, y);
final Drawable minuteHand = mMinuteHand;
if (changed) {
w = minuteHand.getIntrinsicWidth();
h = minuteHand.getIntrinsicHeight();
minuteHand.setBounds(x - (w / 2), y - (h / 3), x + (w / 2), y + (h / 3));
}
minuteHand.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(mSecond, x, y);
// minuteHand = mMinuteHand;
if (seconds) {
w = mSecondHand.getIntrinsicWidth();
h = mSecondHand.getIntrinsicHeight();
mSecondHand.setBounds(x - (w / 2), y - (h / 3), x + (w / 2), y + (h / 3));
}
mSecondHand.draw(canvas);
canvas.restore();
if (scaled) {
canvas.restore();
}
}
MyCount counter = new MyCount(10000, 1000);
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
counter.start();
}
#Override
public void onTick(long millisUntilFinished) {
mCalendar.setToNow();
int hour = mCalendar.hour;
int minute = mCalendar.minute;
int second = mCalendar.second;
mSecond = 6.0f * second;
mSeconds = true;
// mChanged = true;
AnalogClock2.this.invalidate();
// Toast.makeText(mContext, "text", Toast.LENGTH_LONG).show();
}
}
boolean mSeconds = false;
float mSecond = 0;
private void onTimeChanged() {
mCalendar.setToNow();
int hour = mCalendar.hour+4;
int minute = mCalendar.minute+15;
int second = mCalendar.second;
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
String tz = intent.getStringExtra("time-zone");
mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
}
mCalendar = new Time(mtimezone);
onTimeChanged();
invalidate();
}
};
}
Related
I made a custom view that is has 12 circles along a circular path. I would like to implement an onClick listener for each circle. How would I implement that in my custom view? I have also uploaded my code for the custom view. It just extends a View.
public class WatchView extends View {
private Paint mCircleTickPaint;
private Paint mHourPaint;
private Paint mMinutePaint;
private Paint mSecondPaint;
private boolean mShouldTick;
private int mTickSize;
private int mHourColor;
private int mMinuteColor;
private int mSecondColor;
private int mSeconds = 0;
private int mMinutes = 0;
private int mHours = 0;
private Handler handler = new Handler(Looper.getMainLooper());
public WatchView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.watchface,
0, 0);
try {
mShouldTick = a.getBoolean(R.styleable.watchface_shouldTick, true);
mTickSize = a.getInt(R.styleable.watchface_tickSize, 40);
mHourColor = a.getColor(R.styleable.watchface_hourColor, Color.RED);
mMinuteColor = a.getColor(R.styleable.watchface_minuteColor, Color.GREEN);
mSecondColor = a.getColor(R.styleable.watchface_secondColor, Color.BLUE);
} finally {
a.recycle();
}
init();
}
public void init() {
mCircleTickPaint = new Paint();
mCircleTickPaint.setAntiAlias(true);
mCircleTickPaint.setColor(Color.WHITE);
mHourPaint = new Paint();
mHourPaint.setAntiAlias(true);
mHourPaint.setColor(mHourColor);
mMinutePaint = new Paint();
mMinutePaint.setAntiAlias(true);
mMinutePaint.setColor(mMinuteColor);
mSecondPaint = new Paint();
mSecondPaint.setAntiAlias(true);
mSecondPaint.setColor(mSecondColor);
long now = System.currentTimeMillis();
SimpleDateFormat hh = new SimpleDateFormat("hh");
SimpleDateFormat mm = new SimpleDateFormat("mm");
SimpleDateFormat ss = new SimpleDateFormat("ss");
int hours = Integer.parseInt(hh.format(new Date(now)));
int minutes = Integer.parseInt(mm.format(new Date(now)));
int seconds = Integer.parseInt(ss.format(new Date(now)));
int mappedMinutes = (int) Utils.map(minutes, 1, 60, 1, 12);
int reverseSeconds = (60 - seconds) % 12;
int mappedSeconds = (int) Utils.map(reverseSeconds, 1, 60, 1, 12);
this.mHours = hours;
this.mMinutes = mappedMinutes;
this.mSeconds = mappedSeconds;
if (mShouldTick) {
if (null != handler) {
handler.removeCallbacks(mUpdateRunnable);
}
handler.post(mUpdateRunnable);
}
Log.d("WatchView", "Setting the time at: " + mHours + ":" + mMinutes + ":" + mSeconds);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
int centerX = canvas.getWidth() / 2;
int centerY = canvas.getHeight() / 2;
float innerTickRadius = centerX / 2;
for (int tickIndex = 0; tickIndex < 12; tickIndex++) {
float tickRot = (float) (tickIndex * Math.PI * 2 / 12);
float innerX = (float) Math.sin(tickRot) * innerTickRadius;
float innerY = (float) -Math.cos(tickRot) * innerTickRadius;
int reverseSeconds = (60 - mSeconds) % 12;
int mappedSeconds = (int) Utils.map(reverseSeconds, 0, 11, 11, 0);
if (mHours == tickIndex) {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mHourPaint);
} else if (mMinutes == tickIndex) {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mMinutePaint);
} else if (mappedSeconds == tickIndex) {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mSecondPaint);
} else {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mCircleTickPaint);
}
}
}
private Runnable mUpdateRunnable = new Runnable() {
#Override public void run() {
mSeconds += 1;
if (mSeconds > 59) {
mSeconds = 0;
mMinutes += 1;
}
if (mMinutes > 59) {
mMinutes = 0;
mHours += 1;
}
if (mHours > 11) {
mHours = 0;
}
invalidate();
handler.postDelayed(mUpdateRunnable, 1000);
}
};
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int intrinsicSize = ScreenUtils.getScreenWidth(getContext());
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(intrinsicSize, widthSize);
} else {
width = intrinsicSize;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(intrinsicSize, heightSize);
} else {
height = intrinsicSize;
}
int min = Math.min(width, height);
setMeasuredDimension(min, min);
}
}
Em...the title is not clearly, here is my question: i custom a view to display calendar, my logic is when user swipe horizontal it can switch month of current year, when user swipe vertical it can switch year of current month, like image below:
Here is my all code below and i delete some useless code:
public class MonthView extends View {
private static final Region[][] MONTH_REGIONS = new Region[6][7];
private DPCManager mCManager = DPCManager.getInstance();
private DPTManager mTManager = DPTManager.getInstance();
private TextPaint mTextPaint;
private Paint mPaint;
private Scroller mScroller;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
private AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator();
private OnDateChangeListener onDateChangeListener;
private ScaleAnimationListener scaleAnimationListener = new ScaleAnimationListener();
private DPMode mode;
private int indexYear, indexMonth;
private int centerYear, centerMonth;
private int leftYear, leftMonth;
private int rightYear, rightMonth;
private int topYear, topMonth;
private int bottomYear, bottomMonth;
private int width, height;
private int lastHeight, nextHeight;
private int baseSize;
private int sizeDecor, sizeDecor2x, sizeDecor3x;
private int lastPointX, lastPointY;
private int lastMoveX, lastMoveY;
private int criticalWidth, criticalHeight;
private float sizeTextGregorian, sizeTextFestival;
private float offsetYFestival1, offsetYFestival2;
private boolean isSlideV;
private Map<String, BGCircle> circlesAppear = new HashMap<>();
private Map<String, BGCircle> circlesDisappear = new HashMap<>();
private List<String> dateSelected = new ArrayList<>();
public interface OnDateChangeListener {
void onMonthChange(int month);
void onYearChange(int year);
}
public MonthView(Context context) {
this(context, null);
}
public MonthView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
mTextPaint = new TextPaint();
mTextPaint.setTextAlign(Paint.Align.CENTER);
mPaint = new Paint();
}
void setOnDateChangeListener(OnDateChangeListener onDateChangeListener) {
this.onDateChangeListener = onDateChangeListener;
}
void setMode(DPMode mode) {
this.mode = mode;
}
void setDate(int year, int month) {
centerYear = year;
centerMonth = month;
indexYear = 0;
indexMonth = 0;
computeDate();
requestLayout();
invalidate();
}
private void computeDate() {
rightYear = leftYear = centerYear;
topYear = centerYear - 1;
bottomYear = centerYear + 1;
topMonth = centerMonth;
bottomMonth = centerMonth;
rightMonth = centerMonth + 1;
leftMonth = centerMonth - 1;
if (centerMonth == 12) {
rightYear++;
rightMonth = 1;
}
if (centerMonth == 1) {
leftYear--;
leftMonth = 12;
}
if (null != onDateChangeListener) {
onDateChangeListener.onYearChange(centerYear);
onDateChangeListener.onMonthChange(centerMonth);
}
}
#Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
} else {
}
}
boolean isNewEvent = false;
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isNewEvent = true;
lastPointX = (int) event.getX();
lastPointY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
if (isNewEvent) {
if (Math.abs(lastPointX - event.getX()) > 100) {
isSlideV = false;
isNewEvent = false;
} else if (Math.abs(lastPointY - event.getY()) > 50) {
isSlideV = true;
isNewEvent = false;
}
}
if (isSlideV) {
int totalMoveY = (int) (lastPointY - event.getY()) + lastMoveY;
smoothScrollTo(0, totalMoveY);
} else {
int totalMoveX = (int) (lastPointX - event.getX()) + lastMoveX;
smoothScrollTo(totalMoveX, 0);
}
break;
case MotionEvent.ACTION_UP:
if (isSlideV) {
if (Math.abs(lastPointY - event.getY()) > 25) {
if (lastPointY < event.getY()) {
if (Math.abs(lastPointY - event.getY()) >= criticalHeight) {
indexYear--;
centerYear = centerYear - 1;
computeDate();
}
smoothScrollTo(0, height * indexYear);
lastMoveY = height * indexYear;
} else if (lastPointY > event.getY()) {
if (Math.abs(lastPointY - event.getY()) >= criticalHeight) {
indexYear++;
centerYear = centerYear + 1;
computeDate();
}
smoothScrollTo(0, height * indexYear);
lastMoveY = height * indexYear;
}
} else {
}
} else {
if (Math.abs(lastPointX - event.getX()) > 25) {
if (lastPointX > event.getX()) {
if (Math.abs(lastPointX - event.getX()) >= criticalWidth) {
indexMonth++;
centerMonth = (centerMonth + 1) % 13;
if (centerMonth == 0) {
centerMonth = 1;
centerYear++;
}
computeDate();
}
smoothScrollTo(width * indexMonth, 0);
lastMoveX = width * indexMonth;
} else if (lastPointX < event.getX()) {
if (Math.abs(lastPointX - event.getX()) >= criticalWidth) {
indexMonth--;
centerMonth = (centerMonth - 1) % 12;
if (centerMonth == 0) {
centerMonth = 12;
centerYear--;
}
computeDate();
}
smoothScrollTo(width * indexMonth, 0);
lastMoveX = width * indexMonth;
}
} else {
}
}
break;
}
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(measureWidth, measureWidth * 6 / 7F);
}
#Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
width = w;
height = h;
criticalWidth = (int) (1F / 5F * width);
criticalHeight = (int) (1F / 5F * height);
baseSize = w;
int sizeCell = (int) (baseSize / 7F);
sizeDecor = (int) (sizeCell / 3F);
sizeDecor2x = sizeDecor * 2;
sizeDecor3x = sizeDecor * 3;
sizeTextGregorian = baseSize / 20F;
mTextPaint.setTextSize(sizeTextGregorian);
float heightGregorian = mTextPaint.getFontMetrics().bottom - mTextPaint.getFontMetrics().top;
sizeTextFestival = baseSize / 40F;
mTextPaint.setTextSize(sizeTextFestival);
float heightFestival = mTextPaint.getFontMetrics().bottom - mTextPaint.getFontMetrics().top;
offsetYFestival1 = (((Math.abs(mTextPaint.ascent() + mTextPaint.descent())) / 2F) +
heightFestival / 2F + heightGregorian / 2F) / 2F;
offsetYFestival2 = offsetYFestival1 * 2F;
for (int i = 0; i < MONTH_REGIONS.length; i++) {
for (int j = 0; j < MONTH_REGIONS[i].length; j++) {
Region region = new Region();
region.set((j * sizeCell), (i * sizeCell), sizeCell + (j * sizeCell),
sizeCell + (i * sizeCell));
MONTH_REGIONS[i][j] = region;
}
}
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.LTGRAY);
draw(canvas, width * (indexMonth - 1), height * indexYear, leftYear, leftMonth);
draw(canvas, width * indexMonth, height * indexYear, centerYear, centerMonth);
draw(canvas, width * (indexMonth + 1), height * indexYear, rightYear, rightMonth);
draw(canvas, width * indexMonth, height * (indexYear - 1), topYear, topMonth);
draw(canvas, width * indexMonth, height * (indexYear + 1), bottomYear, bottomMonth);
}
private void draw(Canvas canvas, int x, int y, int year, int month) {
canvas.save();
canvas.translate(x, y);
DPInfo[][] info = mCManager.obtainDPInfo(year, month);
for (int i = 0; i < info.length; i++) {
for (int j = 0; j < info[i].length; j++) {
draw(canvas, MONTH_REGIONS[i][j].getBounds(), info[i][j]);
}
}
canvas.restore();
}
private void draw(Canvas canvas, Rect rect, DPInfo info) {
drawGregorian(canvas, rect, info.strG, info.isWeekend);
}
private void drawGregorian(Canvas canvas, Rect rect, String str, boolean isWeekend) {
mTextPaint.setTextSize(sizeTextGregorian);
if (isWeekend) {
mTextPaint.setColor(mTManager.colorWeekend());
} else {
mTextPaint.setColor(mTManager.colorG());
}
canvas.drawText(str, rect.centerX(), rect.centerY(), mTextPaint);
}
private void smoothScrollTo(int fx, int fy) {
int dx = fx - mScroller.getFinalX();
int dy = fy - mScroller.getFinalY();
smoothScrollBy(dx, dy);
}
private void smoothScrollBy(int dx, int dy) {
mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, 500);
invalidate();
}
}
If i swipe vertical to switch year, for example 2015/7-->2016/7-->2017/7, it's run correctly, but now if i swipe horizontal to switch month, for example 2017/7-->2017/6, everything will not display:
That's mean only horizontal and vertical on current month can touch and display correctly, for example the default display month is 2015/7, when i swipe to 2016/7 or 2017/7, i can't get the correct display when i swipe to 2017/6 or 2017/8, only swipe back to 2015/7 to swipe correctly can get the correct display of 2015/6 and 2015/8.
This problem troubled me many days, the coordinates and data of months all correct, i don't know why it happen, hope and thanks for your answer.
I am working with custom view which is in a circle shape. Almost i have done it with creating a custom class and implemented that. But my problem is too show a different progress in a curve shape with different color and which is depends on dynamic data. Here is the image which i have implemented
I want like this http://imgur.com/cmNKWBF.
So my question is how to draw arc (curve shape) progress with different color and with dynamic data.
Help would be appreciated !!
Finally i have resolved this after making some changes in Custom CircleView class. For that i have counted a sweepAngle and startAngle for each region. Here is some part of code i am posting.
I had to show three different regions so i have taken three different Paints and declared variable for each regions. Like,
private float absStart;
private float absSweep;
private float preStart;
private float preSweep;
private float vacStart;
private float vacSweep;
private Paint absPaint;
private Paint prePaint;
private Paint vacPaint;
Now init your all three regions paints. Here i just posting one of them
absPaint = new Paint();
absPaint.setStrokeCap(Paint.Cap.ROUND);
absPaint.setStyle(Paint.Style.STROKE);
absPaint.setStrokeJoin(Paint.Join.ROUND);
absPaint.setColor(Color.parseColor("#eb537a"));
absPaint.setStrokeWidth((float) 22.5);
Now to calculate the area of each region i had created a method named updateAngles() which have three float parameters
public void updateAngles(float absPercent, float prePercent, float vacPercent) {
float total = absPercent + prePercent + vacPercent;
absStart = 0;
absSweep = (absPercent / total) * 360;
preStart = absSweep;
preSweep = (prePercent / total) * 360;
vacStart = absSweep + preSweep;
vacSweep = (vacPercent / total) * 360;
Log.e("Angles are:", absStart + ":" + absSweep + ":" + preStart + ":" + preSweep + ":" + vacStart + ":" + vacSweep);
invalidate();
}
This method will be called in your desired activity after initialize CircleView and call like cv.updateAngles(20,20,60); where cv is object of CircleView.
Now in onDraw() method you need to draw arc for each region.
mInnerRectF.set(45, 45, 330, 330);
canvas.drawArc(mInnerRectF, absStart, absSweep, false, absPaint);
canvas.drawArc(mInnerRectF, preStart, preSweep, false, prePaint);
canvas.drawArc(mInnerRectF, vacStart, vacSweep, false, vacPaint);
So this finally giving me a my desired output.
But if there is depend on different devices like mobile screen , 7 inch and 10 inch tablets then you should use DisplayMetrics for it.
Below code satisfies your requirement.
public class ProgressWidget extends View {
private int percent = 25;
private int radiusOuter = 110, radiusInner = 90;
private Paint mPaintOuter;
private Paint mPaintPercent;
private Paint mInnerCircle, mTextPaint;
private int mCenterX, mCenterY;
private int textSize;
private String mTimedText = percent+"%";
private int desiredWidth = 300;
private int desiredHeight = 300;
private boolean isRunning;
private boolean isMeasured;
public ProgressWidget(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialization();
}
public ProgressWidget(Context context, AttributeSet attrs) {
super(context, attrs);
initialization();
}
public ProgressWidget(Context context) {
super(context);
initialization();
}
private void initialization() {
mPaintOuter = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintOuter.setColor(Color.DKGRAY);
mPaintPercent = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintPercent.setColor(Color.CYAN);
mInnerCircle = new Paint(Paint.ANTI_ALIAS_FLAG);
mInnerCircle.setColor(Color.BLACK);
mTextPaint = new Paint();
mTextPaint.setColor(Color.CYAN);
mTextPaint.setTextSize(textSize);
}
public void getUpdateRadius() {
if (!isMeasured) {
isMeasured = true;
int size = getWidgetWidth() < getWidgetHeight() ? getWidgetWidth() : getWidgetHeight();
radiusOuter = (int) (size * 0.35f);
radiusInner = (int) (size * 0.3f);
textSize = (int) (size * 0.08f);
setTimedTextSize(textSize);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCenterX = getWidth() / 2;
mCenterY = getHeight() / 2;
drawSecCircle(canvas);
drawInnerCircle(canvas);
drawPercentageText(canvas);
}
private void drawInnerCircle(Canvas canvas) {
canvas.drawCircle(mCenterX, mCenterY, radiusInner, mInnerCircle);
}
private void drawSecCircle(Canvas canvas) {
canvas.drawCircle(mCenterX, mCenterY, radiusOuter, mPaintOuter);
canvas.drawArc(new RectF(mCenterX - radiusOuter, mCenterY - radiusOuter, mCenterX + radiusOuter, mCenterY + radiusOuter), -90, percent*3.6f, true, mPaintPercent);
}
public void drawPercentageText(Canvas canvas) {
RectF areaRect = new RectF(mCenterX - radiusInner, mCenterY - radiusInner, mCenterX + radiusInner, mCenterY + radiusInner);
RectF bounds = new RectF(areaRect);
// measure text width
bounds.right = mTextPaint.measureText(mTimedText, 0, mTimedText.length());
// measure text height
bounds.bottom = mTextPaint.descent() - mTextPaint.ascent();
bounds.left += (areaRect.width() - bounds.right) / 2.0f;
bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;
canvas.drawText(mTimedText, bounds.left, bounds.top - mTextPaint.ascent(), mTextPaint);
}
public void setTimedTextSize(int textSize) {
this.textSize = textSize;
mTextPaint.setTextSize(textSize);
}
public void setTimedText(String timedText) {
this.mTimedText = timedText;
invalidate();
}
public void setPercentage(int percent) {
this.percent = percent;
mTimedText = String.valueOf(percent)+"%";
invalidate();
}
#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);
setWidgetWidth((int) (widthSize * 0.6));
setWidgetHeight((int) (heightSize * 0.6));
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(getWidgetWidth(), widthSize);
} else {
width = getWidgetWidth();
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(getWidgetHeight(), heightSize);
} else {
height = getWidgetHeight();
}
setWidgetWidth(width);
setWidgetHeight(height);
getUpdateRadius();
setMeasuredDimension(width, height);
}
public int getWidgetWidth() {
return desiredWidth;
}
public void setWidgetWidth(int clockWidgetWidth) {
this.desiredWidth = clockWidgetWidth;
}
public int getWidgetHeight() {
return desiredHeight;
}
public void setWidgetHeight(int clockWidgetHeight) {
this.desiredHeight = clockWidgetHeight;
}
}
I want to move the seconds hand smoothly and swiftly as I have watched many watches moving their seconds hand swiftly with out making tick tick movements .
I have tried this code from open source and it is working fine
public class AnalogClock1 extends View {
public AnalogClock1(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
private Time mCalendar;
private Drawable mHourHand;
private Drawable mMinuteHand;
private Drawable mSecondHand;
private Drawable mDial;
private int mDialWidth;
private int mDialHeight;
private boolean mAttached;
private final Handler mHandler = new Handler();
private float mMinutes;
private float mHour;
private float mMillisec;
private boolean mChanged;
Context mContext;
public AnalogClock1(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AnalogClock1(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
Resources r = context.getResources();
TypedArray a =
context.obtainStyledAttributes(
attrs, R.styleable.AnalogClock, defStyle, 0);
mContext=context;
// mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
// if (mDial == null) {
mDial = r.getDrawable(R.drawable.clock_dial);
// }
// mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour);
// if (mHourHand == null) {
mHourHand = r.getDrawable(R.drawable.clock_hour);
// }
// mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);
// if (mMinuteHand == null) {
mMinuteHand = r.getDrawable(R.drawable.clock_minute);
mSecondHand = r.getDrawable(R.drawable.clockgoog_minute);
// }
mCalendar = new Time();
mDialWidth = mDial.getIntrinsicWidth();
mDialHeight = mDial.getIntrinsicHeight();
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!mAttached) {
mAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
}
// NOTE: It's safe to do these after registering the receiver since the receiver always runs
// in the main thread, therefore the receiver can't run before this method returns.
// The time zone may have changed while the receiver wasn't registered, so update the Time
mCalendar = new Time();
// Make sure we update to the current time
onTimeChanged();
counter.start();
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAttached) {
counter.cancel();
getContext().unregisterReceiver(mIntentReceiver);
mAttached = false;
}
}
#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));
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mChanged = true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
boolean changed = mChanged;
if (changed) {
mChanged = false;
}
boolean seconds = mSeconds;
if (seconds ) {
mSeconds = false;
}
int availableWidth = 200;
int availableHeight = 200;
int x = availableWidth / 2;
int y = availableHeight / 2;
final Drawable dial = mDial;
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(mHour / 12.0f * 360.0f, x, y);
final Drawable hourHand = mHourHand;
if (changed) {
w = hourHand.getIntrinsicWidth();
h = hourHand.getIntrinsicHeight();
hourHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
hourHand.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(mMinutes / 60.0f * 360.0f, x, y);
//canvas.rotate(mSecond, x, y);
final Drawable minuteHand = mMinuteHand;
if (changed) {
w = minuteHand.getIntrinsicWidth();
h = minuteHand.getIntrinsicHeight();
minuteHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
minuteHand.draw(canvas);
canvas.restore();
canvas.save();
canvas.rotate(mSecond, x, y);
//minuteHand = mMinuteHand;
if (seconds) {
w = mSecondHand.getIntrinsicWidth();
h = mSecondHand.getIntrinsicHeight();
mSecondHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
mSecondHand.draw(canvas);
canvas.restore();
if (scaled) {
canvas.restore();
}
}
MyCount counter = new MyCount(10000, 1000);
public class MyCount extends CountDownTimer{
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
counter.start();
}
#Override
public void onTick(long millisUntilFinished) {
mCalendar.setToNow();
int hour = mCalendar.hour;
int minute = mCalendar.minute;
int second = mCalendar.second;
mSecond=6.0f*second;
mSeconds=true;
//mChanged = true;
AnalogClock1.this.invalidate();
//Toast.makeText(mContext, "text", Toast.LENGTH_LONG).show();
}
}
boolean mSeconds=false;
float mSecond=0;
private void onTimeChanged() {
mCalendar.setToNow();
int hour = mCalendar.hour;
int minute = mCalendar.minute;
int second = mCalendar.second;
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
String tz = intent.getStringExtra("time-zone");
mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
}
onTimeChanged();
invalidate();
}
};
}
Please help me out.
I think that you got to change the values that you are assigning to the Counter class.
in the particular case I think that you should really need to change the values in the Following line inside your code.
MyCount counter = new MyCount(10000, 1000);
please rate if this works.
I have 8 images which are placed circularly on the dial which resembles a speedometer with first image placed at the position which is similar to 0 and the last image on the position similar to 200 or the last value of the speedometer.
Now i want to rotate the needle which is fixed at the base and moves from the first image to last.While the needle rotates,as it moves over the images,the images changes.
The needle moves from first image to the last and moves back to first image.!
Have removed the sensor's code as i didnt wanted and remove the background and major chunk added a new method called reverse() for reversing the movement not able to find where i am going wrong. it just execute the loop once and comes out.
public final class Thermometer extends View
{
private static final String TAG = Thermometer.class.getSimpleName();
private Handler handler;
// drawing tools
private Paint scalePaint;
private RectF scaleRect;
private Paint logoPaint;
private Bitmap logo;
private Matrix logoMatrix;
private float logoScale;
private Paint handPaint;
private Path handPath;
private Paint handScrewPaint;
private Paint backgroundPaint;
// end drawing tools
private Bitmap background; // holds the cached static part
// scale configuration
private static final int totalNicks = 100;
private static final float degreesPerNick = 360.0f / totalNicks;
private static final int centerDegree = 40; // the one in the top center (12
// o'clock)
private static final int minDegrees = -30;
private static final int maxDegrees = 110;
// hand dynamics -- all are angular expressed in F degrees
private boolean handInitialized = false;
private float handPosition = minDegrees;
private float handTarget = minDegrees;
private float handVelocity = 0.0f;
private float handAcceleration = 0.0f;
private long lastHandMoveTime = -1L;
public Thermometer(Context context)
{
super(context);
init();
}
public Thermometer(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public Thermometer(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
}
#Override
protected void onRestoreInstanceState(Parcelable state)
{
Bundle bundle = (Bundle) state;
Parcelable superState = bundle.getParcelable("superState");
super.onRestoreInstanceState(superState);
handInitialized = bundle.getBoolean("handInitialized");
handPosition = bundle.getFloat("handPosition");
handTarget = bundle.getFloat("handTarget");
handVelocity = bundle.getFloat("handVelocity");
handAcceleration = bundle.getFloat("handAcceleration");
lastHandMoveTime = bundle.getLong("lastHandMoveTime");
}
#Override
protected Parcelable onSaveInstanceState()
{
Parcelable superState = super.onSaveInstanceState();
Bundle state = new Bundle();
state.putParcelable("superState", superState);
state.putBoolean("handInitialized", handInitialized);
state.putFloat("handPosition", handPosition);
state.putFloat("handTarget", handTarget);
state.putFloat("handVelocity", handVelocity);
state.putFloat("handAcceleration", handAcceleration);
state.putLong("lastHandMoveTime", lastHandMoveTime);
return state;
}
private void init()
{
handler = new Handler();
initDrawingTools();
}
private void initDrawingTools()
{
// the linear gradient is a bit skewed for realism
logoPaint = new Paint();
logoPaint.setFilterBitmap(true);
logo = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.logo);
logoMatrix = new Matrix();
logoScale = (1.0f / logo.getWidth()) * 0.3f;
logoMatrix.setScale(logoScale, logoScale);
handPaint = new Paint();
handPaint.setAntiAlias(true);
handPaint.setColor(0xff392f2c);
handPaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000);
handPaint.setStyle(Paint.Style.FILL);
handPath = new Path();
handPath.moveTo(0.5f, 0.5f + 0.2f);
handPath.lineTo(0.5f - 0.010f, 0.5f + 0.2f - 0.007f);
handPath.lineTo(0.5f - 0.002f, 0.5f - 0.32f);
handPath.lineTo(0.5f + 0.002f, 0.5f - 0.32f);
handPath.lineTo(0.5f + 0.010f, 0.5f + 0.2f - 0.007f);
handPath.lineTo(0.5f, 0.5f + 0.2f);
handPath.addCircle(0.5f, 0.5f, 0.025f, Path.Direction.CW);
handScrewPaint = new Paint();
handScrewPaint.setAntiAlias(true);
handScrewPaint.setColor(0xff493f3c);
handScrewPaint.setStyle(Paint.Style.FILL);
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec));
Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size)
{
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY)
{
return size;
}
else
{ // (mode == MeasureSpec.UNSPECIFIED)
return getPreferredSize();
}
}
// in case there is no size specified
private int getPreferredSize()
{
return 300;
}
private void drawScale(Canvas canvas)
{
canvas.drawOval(scaleRect, scalePaint);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
for (int i = 0; i < totalNicks; ++i)
{
float y1 = scaleRect.top;
float y2 = y1 - 0.020f;
canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);
if (i % 5 == 0)
{
int value = nickToDegree(i);
if (value >= minDegrees && value <= maxDegrees)
{
String valueString = Integer.toString(value);
canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);
}
}
canvas.rotate(degreesPerNick, 0.5f, 0.5f);
}
canvas.restore();
}
private int nickToDegree(int nick)
{
int rawDegree = ((nick < totalNicks / 2) ? nick : (nick - totalNicks)) * 2;
int shiftedDegree = rawDegree + centerDegree;
return shiftedDegree;
}
private float degreeToAngle(float degree)
{
return (degree - centerDegree) / 2.0f * degreesPerNick;
}
private void drawLogo(Canvas canvas)
{
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(0.5f - logo.getWidth() * logoScale / 2.0f,0.5f - logo.getHeight() * logoScale / 2.0f);
int color = 0x00000000;
float position = getRelativeTemperaturePosition();
if (position < 0)
{
color |= (int) ((0xf0) * -position); // blue
}
else
{
color |= ((int) ((0xf0) * position)) << 16; // red
}
Log.d(TAG, "*** " + Integer.toHexString(color));
LightingColorFilter logoFilter = new LightingColorFilter(0xff338822,color);
logoPaint.setColorFilter(logoFilter);
canvas.drawBitmap(logo, logoMatrix, logoPaint);
canvas.restore();
}
private void drawHand(Canvas canvas)
{
if (handInitialized)
{
float handAngle = degreeToAngle(handPosition);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.rotate(handAngle, 0.5f, 0.5f);
canvas.drawPath(handPath, handPaint);
canvas.restore();
canvas.drawCircle(0.5f, 0.5f, 0.01f, handScrewPaint);
}
}
private void drawBackground(Canvas canvas)
{
if (background == null)
{
Log.w(TAG, "Background not created");
}
else
{
canvas.drawBitmap(background, 0, 0, backgroundPaint);
}
}
#Override
protected void onDraw(Canvas canvas)
{
drawBackground(canvas);
float scale = (float) getWidth();
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(scale, scale);
drawLogo(canvas);
drawHand(canvas);
canvas.restore();
moveHand();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
Log.d(TAG, "Size changed to " + w + "x" + h);
regenerateBackground();
}
private void regenerateBackground()
{
// free the old bitmap
if (background != null)
{
background.recycle();
}
background = Bitmap.createBitmap(getWidth(), getHeight(),Bitmap.Config.ARGB_8888);
Canvas backgroundCanvas = new Canvas(background);
float scale = (float) getWidth();
backgroundCanvas.scale(scale, scale);
}
private boolean handNeedsToMove()
{
return Math.abs(handPosition - handTarget) > 0.01f;
}
private void moveHand()
{
setHandTarget(maxDegrees);
if (!handNeedsToMove())
{
return;
}
if (lastHandMoveTime != -1L)
{
long currentTime = System.currentTimeMillis();
float delta = (currentTime - lastHandMoveTime) / 1500.0f;
float direction = Math.signum(handVelocity);
if (Math.abs(handVelocity) < 90.0f)
{
handAcceleration = 5.0f * (handTarget - handPosition);
}
else
{
handAcceleration = 0.0f;
}
handPosition += handVelocity * delta;
handVelocity += handAcceleration * delta;
if ((handTarget - handPosition) * direction < 0.01f * direction)
{
handPosition = handTarget;
handVelocity = 0.0f;
handAcceleration = 0.0f;
lastHandMoveTime = -1L;
}
else
{
Log.i("inside ","direction else loop");
lastHandMoveTime = System.currentTimeMillis();
}
invalidate();
}
else
{
Log.i("inside ","direction first final else loop");
lastHandMoveTime = System.currentTimeMillis();
moveHand();
}
if(handPosition==maxDegrees)
{
reverse();
}
}
public void reverse()
{
handAcceleration=1.0f;
Log.i("Hand Velocity",Float.toString(handVelocity));
Log.i("Inside","next loop");
setHandTarget(minDegrees);
if (!handNeedsToMove())
{
return;
}
if (lastHandMoveTime != -1L)
{
long currentTime = System.currentTimeMillis();
float delta = (currentTime -lastHandMoveTime) / 1500.0f;
float direction = Math.signum(handVelocity);
if (Math.abs(handVelocity) <90.0f)
{
handAcceleration = 5.0f * (handPosition+handTarget);
Log.i("Hand Acceleration",Float.toString(handAcceleration));
}
else
{
handAcceleration = 0.0f;
}
handPosition -= handVelocity * delta;
handVelocity -= handAcceleration *delta;
if ((handPosition + handTarget) * direction < 0.01f * direction)
{
handPosition = handTarget;
handVelocity = 0.0f;
handAcceleration = 0.0f;
lastHandMoveTime =-1L;
}
else
{
lastHandMoveTime = System.currentTimeMillis();
}
invalidate();
}
else
{
lastHandMoveTime = System.currentTimeMillis();
reverse();
}
}
private float getRelativeTemperaturePosition()
{
if (handPosition < centerDegree)
{
return -(centerDegree - handPosition)/ (float) (centerDegree - minDegrees);
}
else
{
return (handPosition - centerDegree)/ (float) (maxDegrees - centerDegree);
}
}
private void setHandTarget(float temperature)
{
if (temperature < minDegrees)
{
temperature = minDegrees;
}
else if (temperature > maxDegrees)
{
temperature = maxDegrees;
}
handTarget = temperature;
handInitialized = true;
invalidate();
}
}
Just initialize the hand position to max degree and in the moveHand() method setHandTarget(minDegrees) for anticlockwise rotation It worked for me.
For clockwise rotation just do the opposite.
I have solved hand showing and moving inserting this in main activity:
View termometro = (View)findViewById(R.id.termometro);
termometro.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
It has to do with hardware acceleration