等待 android 中的多点触控输入
Waiting for multi-touch input in android
我正在尝试做一个多点触控应用程序。动机是写一个盲文应用程序,它将能够阅读盲文。
我正在使用 this 作为盲文参考。
这是代码段:
@Override
public boolean onTouchEvent(MotionEvent event) {
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
// get masked (not specific to a pointer) action
int maskedAction = event.getActionMasked();
switch (maskedAction & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN: {
// We have a new pointer. Lets add it to the list of pointers
PointF f = new PointF();
f.x = event.getX(pointerIndex);
f.y = event.getY(pointerIndex);
mActivePointers.put(pointerId, f);
parseBraille();
break;
}
case MotionEvent.ACTION_MOVE: { // a pointer was moved
for (int size = event.getPointerCount(), i = 0; i < size; i++) {
PointF point = mActivePointers.get(event.getPointerId(i));
if (point != null) {
point.x = event.getX(i);
point.y = event.getY(i);
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: {
mActivePointers.remove(pointerId);
break;
}
}
invalidate();
return true;
}
private void showMsg(String msg){
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
private void parseBraille(){
if (mActivePointers.size() == 1){
showMsg("a");
}
else if (mActivePointers.size() == 2){
double x0 = mActivePointers.get(0).x;
double y0 = mActivePointers.get(0).y;
double x1 = mActivePointers.get(1).x;
double y1 = mActivePointers.get(1).y;
if (Math.abs(mActivePointers.get(0).x - mActivePointers.get(1).x) < 50){
showMsg("b");
}
}
}
这里发生的事情是,当我用两根手指触摸时,我想得到 "b" 作为响应,但我得到 "a" 因为第一个手指然后 [=23] =].
如何解决这个问题?
您将一次获得一个触摸事件,因此您需要修改您的方法。我看到两个解决方案:(1)触摸后,等待给定的时间,以防用户按下另一个手指,或者(2)使用第一个 UP 事件,然后收集手指总数以确定合适的字母。
您可以使用两种不同的方法来解决这个问题:
机器学习:更准确,更费时。你让一些人表演所有的盲文字母表。您记录所有执行的字母(让我们称它们为 手势)并使用它们来训练 模型。该模型将用于在运行时识别新手势。
有限状态机:不太准确,但最快的方法,您现在正在尝试的方法。你基本上必须:
记录一个手势。从ACTION_DOWN
到ACTION_UP
记录了您收到的所有MotionEvent
。
使用所有记录的 MotionEvent
个实例识别手势。
您的代码中的问题是您试图识别 ACTION_POINTER_DOWN
事件中的手势(方法 parseBraille
)。每当用户在触摸屏上按下手指时都会触发此事件,第一次按下手指时也会触发此事件。在那一刻,你将无法识别手势。您必须等待手势结束。
我正在尝试做一个多点触控应用程序。动机是写一个盲文应用程序,它将能够阅读盲文。
我正在使用 this 作为盲文参考。
这是代码段:
@Override
public boolean onTouchEvent(MotionEvent event) {
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
// get masked (not specific to a pointer) action
int maskedAction = event.getActionMasked();
switch (maskedAction & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN: {
// We have a new pointer. Lets add it to the list of pointers
PointF f = new PointF();
f.x = event.getX(pointerIndex);
f.y = event.getY(pointerIndex);
mActivePointers.put(pointerId, f);
parseBraille();
break;
}
case MotionEvent.ACTION_MOVE: { // a pointer was moved
for (int size = event.getPointerCount(), i = 0; i < size; i++) {
PointF point = mActivePointers.get(event.getPointerId(i));
if (point != null) {
point.x = event.getX(i);
point.y = event.getY(i);
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: {
mActivePointers.remove(pointerId);
break;
}
}
invalidate();
return true;
}
private void showMsg(String msg){
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
private void parseBraille(){
if (mActivePointers.size() == 1){
showMsg("a");
}
else if (mActivePointers.size() == 2){
double x0 = mActivePointers.get(0).x;
double y0 = mActivePointers.get(0).y;
double x1 = mActivePointers.get(1).x;
double y1 = mActivePointers.get(1).y;
if (Math.abs(mActivePointers.get(0).x - mActivePointers.get(1).x) < 50){
showMsg("b");
}
}
}
这里发生的事情是,当我用两根手指触摸时,我想得到 "b" 作为响应,但我得到 "a" 因为第一个手指然后 [=23] =].
如何解决这个问题?
您将一次获得一个触摸事件,因此您需要修改您的方法。我看到两个解决方案:(1)触摸后,等待给定的时间,以防用户按下另一个手指,或者(2)使用第一个 UP 事件,然后收集手指总数以确定合适的字母。
您可以使用两种不同的方法来解决这个问题:
机器学习:更准确,更费时。你让一些人表演所有的盲文字母表。您记录所有执行的字母(让我们称它们为 手势)并使用它们来训练 模型。该模型将用于在运行时识别新手势。
有限状态机:不太准确,但最快的方法,您现在正在尝试的方法。你基本上必须:
记录一个手势。从
ACTION_DOWN
到ACTION_UP
记录了您收到的所有MotionEvent
。使用所有记录的
MotionEvent
个实例识别手势。
您的代码中的问题是您试图识别 ACTION_POINTER_DOWN
事件中的手势(方法 parseBraille
)。每当用户在触摸屏上按下手指时都会触发此事件,第一次按下手指时也会触发此事件。在那一刻,你将无法识别手势。您必须等待手势结束。