Reputation: 6402
I'm developing a watch face and want to rotate the second's hand 1.2 degrees in 1/5 of a second.
Why these numbers?
1) 360 degrees / 60 seconds = 6 degress per second
2) 6 degrees / 5 = 1.2 degrees (rotates 1.2 degrees in a fifth of a second).
Below is the normal rotation (6 degress in a second).
The image above spends one second to rotate 6 degrees.
My question is: How to spends one fifth of a second to rotate 1.2 degress?
This is my code:
private void drawClassicSecondsHand(Canvas canvas) {
final int seconds = (mCalendar.get(Calendar.SECOND));
final float secondsRotation = seconds * 6;
float originRadius = complicationHandBitmap.getWidth() / 2f;
float secondsAreaCenterX = mCenterX - (float) (mCenterX * 0.45);
canvas.rotate(secondsRotation, secondsAreaCenterX, mCenterY);
classicSecondsComplication.draw(
canvas,
secondsAreaCenterX,
mCenterY,
classicComplicationRadius,
complicationHandBitmap,
originRadius);
}
The above method is called in the onDraw
method of my watch face service.
public void onDraw(Canvas canvas, Rect bounds) {
...
drawClassicSecondsHand(Canvas canvas);
}
Upvotes: 1
Views: 567
Reputation: 4784
I'm not sure where your onDraw
method is called from right now, but updating continuously is not good from a battery life point of view.
If you create a new project in Android Studio and select Wear OS and the analog watch face template you'll see a better way to do it. At the very bottom they set up a message handler that will trigger redraws of the watch face at a specific interval (in interactive mode).
/**
* Handle updating the time periodically in interactive mode.
*/
private void handleUpdateTimeMessage() {
invalidate();
if (shouldTimerBeRunning()) {
long timeMs = System.currentTimeMillis();
long delayMs = INTERACTIVE_UPDATE_RATE_MS
- (timeMs % INTERACTIVE_UPDATE_RATE_MS);
mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
}
}
(There are more parts to it than the snippet above, but everything is in the sample watch face.)
In this example the INTERACTIVE_UPDATE_RATE_MS is set to a second. All you have to do is set it to 200ms, and your watch face will update five times per second. Rotate the canvas 1.2 degrees each time and you'll have the desired second hand movement.
Upvotes: 2
Reputation: 159106
You need to include the millisecond in the calculation.
You should also get rid of excessive parentheses and the unnecessary cast.
final int seconds = mCalendar.get(Calendar.SECOND);
final int millis = mCalendar.get(Calendar.MILLISECOND);
final float secondsRotation = (seconds + millis / 1000f) * 6;
The f
at the end of the 1000f
literal makes it a float, preventing integer math truncation issues.
That means millis
is promoted to float, so the result of division is float.
That in turn promotes seconds
to float, so the result of addition is float.
That in turn promotes 6
to float, so the result of multiplication is float.
There is then no need to cast the result.
Upvotes: 2