2015-12-27 2 views
1

Я пытаюсь сделать приложение с несколькими касаниями. Мотивация заключается в написании приложения Брайля, которое сможет читать шрифт Брайля.В ожидании ввода мультитач в 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».

Как решить эту проблему?

ответ

1

Вы можете использовать два различных подхода к решению этой проблемы:

  1. Machine Learning: точное, время дорого. Вы просите некоторых людей выполнить все алфавиты Брайля. Вы записываете все выполненные буквы (назовем их жесты) и используйте их для обучения модели . Эта модель будет использоваться для распознавания новых жестов во время выполнения.

  2. Конечный автомат: менее точный, быстрый способ, тот, который вы пытаетесь прямо сейчас. Вы в основном должны:

    1. Запишите жест. От ACTION_DOWN до ACTION_UP записывается все MotionEvent, которые вы получаете.

    2. Признать жест, используя все зарегистрированные MotionEvent экземпляры.

Проблема в коде является то, что вы пытаетесь распознать жест (метод parseBraille) внутри ACTION_POINTER_DOWN события. Это событие будет запущено каждый раз, когда пользователь нажимает пальцем на сенсорный экран, поэтому также при первом нажатии пальцем. В этот момент вы не сможете распознать жест. Вы должны ждать окончания жестов.

+0

Машинное обучение - хороший вариант. Я попробую! – Priyabrata

0

Вы будете получать события касания по одному, поэтому вам нужно изменить свой подход. Я вижу два решения: (1) После касания подождите определенное количество времени, если пользователь нажимает другой палец, или (2) использует первое событие UP, а затем собирает общее количество пальцев для определения соответствующей буквы.

+0

В случае брайля необходимо иметь параллельное касание, так как можно использовать событие up? Можете ли вы привести пример? – Priyabrata

+0

У меня нет кода, который действительно так полезен, но моя основная идея заключается в том, что в событии DOWN любое письмо считается ориентировочным, где вы можете отображать его для удобства пользователя, но в основном сохранить его на потом. Когда вы получаете событие ACTION_UP, вы считаете его официальным. Другими словами, вместо отображения буквы parseBraille() сохраняет ее в переменной, а затем в ACTION_UP вы извлекаете ее из переменной и отправляете ее в showMsg(). Это можно было бы сделать в ACTION_POINTER_UP, но тогда вам придется беспокоиться о нескольких событиях. –

Смежные вопросы