2

我目前正在开发一个 Android 应用程序,该应用程序允许用户在屏幕上左右移动手指时演奏小提琴。当他们停止移动手指并且小提琴的弓停止移动时,我希望音乐停止播放。

我正在使用典型的 onTouchEvent 来捕获移动手势,现在我想知道检测用户的最佳方法是用户仍在触摸屏幕,但没有移动他们的手指。

这是我目前的代码,带有一个非常意大利面的功能来检测运动量,这会遇到以下两个问题:

1:当用户从左向右移动时,它会在瞬间将其注册为没有移动并停止声音。

2:你的手指不可能完全静止,我需要允许少量的动作。

任何人都可以提出比以下检测缺乏运动的正确方法吗?

public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {

        audio.start();
        bowImage.setY(430);

    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {

        float posX = event.getX();

        if ( detectValidMovement(posX) ) {
            bowImage.setX(posX);
            audio.start();
        } else {
            audio.pause();
        }


    } else if (event.getAction() == MotionEvent.ACTION_UP) {

        audio.pause();

    }
    return true;
}



private boolean detectValidMovement(float posX) {

    int newX = Math.round(posX);

    if (oldX > 0) {

        int distanceMoved = newX - oldX;

        if (oldX != newX) {
            oldX = newX;
            return true;
        } else {
            oldX = newX;
            return false;
        }
    } else {
        oldX = newX;
    }
    return false;   
}
4

1 回答 1

1

还有其他因素在起作用。似乎有一个大约 10 像素的默认触摸“斜率”。这意味着onTouchEvent不会为低于该阈值的任何内容触发。因此,您需要确定它们是否在完全不依赖的情况下停止onTouchEvent。一种方法是在lastTouched每次运行时设置一个来设置时间,并运行一个计时器循环来检查它与当前时间的对比。

现在,如果您想要一个高于 10px 的阈值,您还必须自己安排。就像是:

final int threshold = 25;

private boolean detectValidMovement(float posX) {

    int newX = Math.round(posX.getX());
    double distance = Math.abs(newX - oldX);
    oldX = newX;
    if(distance < threshold)
        return false;

    return true;
}

请注意使用Math.abs()来检查两个方向,并且这只检查 X 运动。我假设这就是您从代码示例中关心的全部内容。

这就是你需要的那部分。检查oldX > 0没有多大意义,因为移动无关紧要。检查oldX != newX由 覆盖distance < threshold,因此您可以摆脱它。

更棘手的部分是设置计时器以防onTouchEvent不触发。

于 2012-10-19T16:03:43.487 回答