[英]Move Minute hand in Android clock
I am trying to write a simple proof of concept app that allows a user to rotate minute hand of a clock. 我正在尝试编写一个简单的概念证明应用程序,允许用户旋转时钟的分针。 I am having hard time coming up with the right logic for OnTouchEvent. 我很难为OnTouchEvent提供正确的逻辑。
So far I have the following code: 到目前为止,我有以下代码:
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
//find an approximate angle between them.
float dx = x-cx;
float dy = y-cy;
double a=Math.atan2(dy,dx);
this.degree = Math.toDegrees(a);
this.invalidate();
}
return true;
}
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
boolean changed = mChanged;
if (changed) {
mChanged = false;
}
int availableWidth = getRight() - getLeft();
int availableHeight = getBottom() - getTop();
int x = availableWidth / 2;
int y = availableHeight / 2;
cx = x;
cy = y;
final Drawable dial = mDial;
int w = dial.getIntrinsicWidth() + 100;
int h = dial.getIntrinsicHeight() + 100;
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();
float hour = mHour / 12.0f * 360.0f;
canvas.rotate(hour, x, y);
final Drawable hourHand = mHourHand;
if (changed) {
w = hourHand.getIntrinsicWidth() + 30;
h = hourHand.getIntrinsicHeight() + 30;
hourHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
hourHand.draw(canvas);
canvas.restore();
canvas.save();
float minute = mMinutes / 60.0f * 360.0f;
if (bearing == 0)
{
canvas.rotate(minute, x, y);
}
else
{
canvas.rotate((float)bearing, x, y);
}
final Drawable minuteHand = mMinuteHand;
if (changed) {
w = minuteHand.getIntrinsicWidth() + 30;
h = minuteHand.getIntrinsicHeight() + 30;
minuteHand.setBounds(x - w, y - h, x + w, y + h);
}
minuteHand.draw(canvas);
canvas.restore();
if (scaled) {
canvas.restore();
}
}
Then based on that, my OnDraw method rotates the minute hand to the specified "this.degree"(just calls canvas.rotate). 然后基于此,我的OnDraw方法将分针旋转到指定的“this.degree”(只调用canvas.rotate)。 I am assuming my math is off here. 我假设我的数学不在这里。 I tried to follow the example here: Calculate angle for rotation in Pie Chart , but that's still not rotating the minute hand correctly. 我试着按照这里的例子: 在饼图中计算旋转角度 ,但仍然没有正确旋转分针。 Any help would be appreciated. 任何帮助,将不胜感激。
The math looks correct. 数学看起来正确。 Your calculations should give you the angle of the touch event, where a touch that is to the exact right of the center point should give you 0 degrees. 您的计算应该为您提供触摸事件的角度,其中触摸位于中心点的正确右侧应该为0度。
A few things to watch out for 有几点需要注意
Canvas.rotate(float, float, float)
method, or add an additional translation seperately, to make sure that you are rotating around the correct point. 旋转时,您需要使用3 arg Canvas.rotate(float, float, float)
方法,或单独添加其他平移,以确保绕正确的点旋转。 Without any translation, it will rotate around (0,0) (the top left corner of the view) 没有任何平移,它将围绕(0,0)旋转(视图的左上角) More on rotation: Rotation always happens around the "current" (0,0) point. 更多关于旋转:旋转总是发生在“当前”(0,0)点附近。 By "current", I mean the (0,0) point after the current matrix has been applied. “当前”是指当前矩阵应用后的(0,0)点。 When you first enter onDraw, the (0,0) point should be the upper-left corner of the view. 首次输入onDraw时,(0,0)点应该是视图的左上角。 Whenever you apply a translation/scaling/etc, you will potentially change where the (0,0) point is, relative to the view. 无论何时应用平移/缩放/等,您都可能会相对于视图更改(0,0)点的位置。
I think something like the following should work, in regards to setting the correct center of rotation: 在设置正确的旋转中心方面,我认为以下内容应该有效:
//first we save the initial matrix, so we can easily get
//back to this state after we're done rotating
canvas.save();
//I *think* you need to negate the center offsets here,
//because you are conceptually moving the canvas, rather
//than moving the center directly
canvas.translate(-cx, -cy);
//<perform the rotation and draw the clock hand>
//...
//and now restore the matrix back to the initial state
canvas.restore();
Your calculation is good for measuring angle for minutes hand to rotate in corresponding quadrants in analog clock... here with little bit changes can make either minutes or hours hand to rotate at the touch position....call the below method in onTouch() method for action move 你的计算有利于测量分钟手在模拟时钟的相应象限中旋转的角度...这里有一点点改变可以让分钟或小时手在触摸位置旋转....在onTouch中调用以下方法( )动作移动的方法
public float getRotationAngle(float x, float y) {
float dx = x - cx;
float dy = y - cy;
double a = Math.atan2(dy, dx);
double degree = Math.toDegrees(a)+90;
if(angle<0){
degree=degree+360;
}
return (float) degree;
}
i have this approach with as vectors concept for calculating the angle but if little bit more than your code if u want i will give that logic.... 我有这种方法用于计算角度的矢量概念,但如果你想要的话,如果你想要的话,我会给出那个逻辑....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.