简体   繁体   English

在Android时钟中移动分钟

[英]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 有几点需要注意

  • Make sure that you're rotating in the correct direction. 确保您以正确的方向旋转。 It is hard to keep this straight, and thus easy to screw it up 很难保持这种直,因此容易搞砸
  • Make sure that you're taking into account that a value of 0 means that the minute hand should be pointing to the right. 确保您考虑到值为0表示分针应指向右侧。 For example, if you start out with a minute hand that is pointing upwards, you would have to add/subtract 90 degrees to the result of your calculation (depending on the direction of rotation - not sure which is correct offhand) 例如,如果你从一个指向上方的分针开始,你必须在计算结果上加/减90度(取决于旋转方向 - 不确定哪个是正确的)
  • Make sure that (cx, cy) is the center point around which you want to calculate the angle 确保(cx,cy)是您想要计算角度的中心点
  • When rotating, you'll need to either use the 3 arg 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM