我目前正在制作一个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;
}
答案 0 :(得分:1)
还有其他因素在起作用。有seems to be默认触摸“slop”约10px。这意味着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
无法触发。