Android 通过手势设置模拟时钟,顺时针或逆时针触摸分针

Android 通过手势设置模拟时钟,顺时针或逆时针触摸分针,android,animation,gesture-recognition,ontouch,Android,Animation,Gesture Recognition,Ontouch,我一直在尝试制作一个类,让用户可以设置一个模拟时钟的时间。为了设置当前时间,他们必须顺时针或逆时针移动分针,而不是时针。时针会根据分针的进度自动移动,但我不能正确地移动时针。它并不是每次经过12点和6点时都有一个平稳的运动,在这里有角度临界点 这是我目前为止的训练。十二点钟时,角度等于0度,当然是最小角度,六点钟时,角度等于180度,是最大角度。从十二到六(顺时针),我们有正角度(0180),从六到十二(顺时针),我们有负角度(-180,0)。这没关系,但如果我想根据分针的进度计算出时针的正确位

我一直在尝试制作一个类,让用户可以设置一个模拟时钟的时间。为了设置当前时间,他们必须顺时针或逆时针移动分针,而不是时针。时针会根据分针的进度自动移动,但我不能正确地移动时针。它并不是每次经过12点和6点时都有一个平稳的运动,在这里有角度临界点

这是我目前为止的训练。十二点钟时,角度等于0度,当然是最小角度,六点钟时,角度等于180度,是最大角度。从十二到六(顺时针),我们有正角度(0180),从六到十二(顺时针),我们有负角度(-180,0)。这没关系,但如果我想根据分针的进度计算出时针的正确位置,我必须将该角度转换为0-360度范围

这里是我处理手势的地方:

@Override
public boolean onTouch(View v, MotionEvent event) {

    // Clock is the clock sphere and the minutes hand.
    final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
    final float yc = clock.getTranslationY() + (clock.getHeight() / 2);

    final float x = event.getX();
    final float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        clock.clearAnimation();
        mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
        break;

    case MotionEvent.ACTION_MOVE:

        /**
         * Translate angles from [-179,179] to [0,360] to be able to move 
         * hours hand properly.
         */

        // Start Angle
        mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
        mMinutesPrevAngle = mMinutesCurrAngle;

        // Finish angle
        mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
        mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);

        if ((mMinutesCurrAngle > mMinutesPrevAngle)) {
            // Clockwise between 12 and 6
            mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
        } else if ((mMinutesCurrAngle < mMinutesPrevAngle)) {
            // counter-Clockwise between 6 and 12
            mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
        } else if ((mMinutesCurrAngle > mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
            // Clockwise between 6 and 12
            mHoursCurrAngle = mLastSpinHoursAngle + (- mMinutesCurrAngle / 12);
        } else if ((mMinutesCurrAngle < mMinutesPrevAngle) && (mMinutesCurrAngle < 0)) {
            // counter-Clockwise between 6 and 12
            mHoursCurrAngle = mLastSpinHoursAngle + (mMinutesCurrAngle / 12);
        }

        newSpin();

        // Transelate angles to the original format to represent them properly.
        mMinutesPrevAngle = translate360Angle(mMinutesPrevAngle);
        mMinutesCurrAngle = translate360Angle(mMinutesCurrAngle);

        animate(clock, mMinutesPrevAngle, mMinutesCurrAngle, 0);
        animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
        mHoursPrevAngle = mHoursCurrAngle;
        break;

    case MotionEvent.ACTION_UP:
        break;        
    }
    return true;
}
@覆盖
公共布尔onTouch(视图v,运动事件){
//时钟是时钟球体和分针。
最终浮点xc=clock.getTranslationX()+(clock.getWidth()/2);
最终浮点yc=clock.getTranslationY()+(clock.getHeight()/2);
最终浮点x=event.getX();
最终浮点y=event.getY();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
clock.clearAnimation();
mMinutesCurrAngle=Math.toDegrees(Math.atan2(x-xc,yc-y));
打破
case MotionEvent.ACTION\u移动:
/**
*将角度从[-179179]平移到[0360],以便能够移动
*小时数正确。
*/
//起始角
mMinutesCurrAngle=set360Angle(mMinutesCurrAngle);
mm螺母旋转角度=mm螺母旋转角度;
//完成角
mminutescurrange=Math.toDegrees(Math.atan2(event.getX()-xc,yc-event.getY());
mMinutesCurrAngle=set360Angle(mMinutesCurrAngle);
如果((mm螺母转角>mm螺母转角)){
//顺时针方向在12和6之间
mHoursCurrAngle=mLastSpinHoursAngle+(mm螺母currangle/12);
}否则,如果((mm螺母转角mMinutesCurrAngle)&(mMinutesCurrAngle<0)){
//顺时针方向在6和12之间
mHoursCurrAngle=mLastSpinHoursAngle+(-mmnutescurrangle/12);
}否则如果((mMinutesCurrAngle
这里是我转换角度的地方:

    /**
     * Translate angles from [-179,179] to [0,360] to be able to move 
     * hours hand properly.
     * @param minutesAngle
     * @return
     */
    private double set360Angle(double angle) {
        if (angle < 0) return (360 + angle); 
        else return angle;
    }

    /**
     * Transelate angles to the original format to represent them properly.
     * @param angle
     * @return
     */
    private double translate360Angle(double angle) {
        if (angle > 180) return (-360 + angle);
        else return angle;
    }
/**
*将角度从[-179179]平移到[0360],以便能够移动
*小时数正确。
*@param分钟角
*@返回
*/
专用双角度(双角度){
如果(角度<0)返回(360+角度);
否则返回角;
}
/**
*将角度转换为原始格式以正确表示它们。
*@param角
*@返回
*/
专用双平移360角(双角度){
如果(角度>180)返回(-360+角度);
否则返回角;
}
在这里,我知道如果分针开始新的旋转:

private void newSpin() {

    if (translate360Angle(mMinutesPrevAngle) < 0 && translate360Angle(mMinutesCurrAngle) > 0) {
            // New Spin clockwise
            // I must remember hour hand angle
            mLastSpinHoursAngle = mHoursPrevAngle;
        } else if (translate360Angle(mMinutesPrevAngle) > 0 && translate360Angle(mMinutesCurrAngle) < 0) {
            // New Spin counter-clockwise
            // I must remember hour hand angle
            mLastSpinHoursAngle = mHoursPrevAngle;
        }
    }
private void newSpin(){
如果(平移360角(mm螺母旋转角度)<0和平移360角(mm螺母旋转角度)>0){
//新的顺时针旋转
//我必须记住时针角度
mLastSpinHoursAngle=mHoursPrevAngle;
}否则,如果(平移360角度(mm螺母旋转角度)>0和平移360角度(mm螺母旋转角度)<0){
//新的逆时针旋转
//我必须记住时针角度
mLastSpinHoursAngle=mHoursPrevAngle;
}
}

谁能帮我一点忙吗?如果有人能帮我,我保证把你的名字写在我第一个未出生的女儿身上。。。开玩笑。

我发现了问题所在

问题在于newSpin()方法中的“if条件”。在这里,在检查条件之前,我将角度转换为原始格式(从0度到180度,十二点到六点,顺时针,从-180度到0度,六点到十二点,也是顺时针)。所以,检查用户是否用分针开始一个新的旋转,它是在用户每次通过六点而不是十二点时加/减一个新的旋转

所以,我确实修正了它,修改了这些条件,并检查了360度格式的分针角度,以前的和当前的。现在,如果前一个角度大于355度,而当前角度小于5度,我将向mSpinNumber添加一个新的旋转。同样地,如果前一个角度小于5度,而当前角度大于355度,我将旋转减去mSpinNumber。我还将方法的名称从newSpin()更改为calculateHourHandAngle()

现在我可以知道用户设定的时间,因为我知道指针的初始位置,旋转的次数和分针角度

private void calculateHourHandAngle() {

    if ((mMinutesPrevAngle > 355) && (mMinutesCurrAngle < 5)) {
        // New Spin clockwise
        mSpinNumber++;
    } else if ((mMinutesPrevAngle < 5) && (mMinutesCurrAngle > 355)) {
        // New Spin counter-clockwise
        mSpinNumber--;
    }
    mHoursCurrAngle = (mSpinNumber * (360/12)) + (mMinutesCurrAngle / 12);
}
@Override
public boolean onTouch(View v, MotionEvent event) {

    // Clock is the clock sphere and the minutes hand.
    final float xc = clock.getTranslationX() + (clock.getWidth() / 2);
    final float yc = clock.getTranslationY() + (clock.getHeight() / 2);

    final float x = event.getX();
    final float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        clock.clearAnimation();
        hour.clearAnimation();
        mMinutesCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
        break;

    case MotionEvent.ACTION_MOVE:

        /**
         * Translate angles from [-179,179] to [0,360] to be able to move 
         * hours hand properly.
         */

        // Start Angle
        mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);
        mMinutesPrevAngle = mMinutesCurrAngle;

        // Finish angle
        mMinutesCurrAngle = Math.toDegrees(Math.atan2(event.getX() - xc, yc - event.getY()));
        mMinutesCurrAngle = set360Angle(mMinutesCurrAngle);

        calculateHourHandAngle();

        animate(clock, translate360Angle(mMinutesPrevAngle), translate360Angle(mMinutesCurrAngle), 0);
        animate(hour, mHoursPrevAngle, mHoursCurrAngle, 0);
        mHoursPrevAngle = mHoursCurrAngle;
        break;

    case MotionEvent.ACTION_UP:
        break;        
    }
    return true;
}