wild_swift (wild_swift) wrote,
wild_swift
wild_swift

Пользовательский ввод на Android. Эпизод первый. Скрытые проблемы.

Сегодня будет первая часть моего эпоса о том, как все прекрасно в мире обработки пользовательского ввода на Android. И поведаю я о том, как в Android устроен multi-touch.


Вообще, принципы multi-touch в Android простые. Есть события DOWN, UP, FINGER_DOWN, FINGER_UP, которые, я думаю, семантически понятны. (уточню только, что события с приставкой finger случаются начиная со второго пальца) Событие содержит координаты текущих пальцев, и все казалось бы хорошо, но есть одно «но». Но это кроется в алгоритме нумерации пальцев, и постигать это «но» пришлось долгими тернистыми путями. И так алгоритм.



  • Первый палец – опущенный палец всегда помечается 0

  • Каждое последующее событие о том, что коснулись новым пальцем, приходит со своим индексом. Что бы однозначно идентифицировать новый палец нам надо вставить информацию о нем в массив, сдвинув индексы пальцев, больше либо равных новому индексу на единицу. (т.е. если у нас пользователь уже прикоснулся двумя пальцами и нам поступило событие FINGER_DOWN с индексом 1, то теперь информация о состоянии второго пальца будет приходить не во второй ячейке массива, а в третьей, во второй же будет храниться информация о состоянии нового пальца).

  • Если приходит событие о том, что палец оторвали от поверхности экрана, то все аналогично, нам требуется удалить выбранный индекс, и сдвинуть следующие за ним на единицу.


Постигал я эти правила, когда делал распозновалку многопальцовых жестов при помощи декомпозиции их в параллельный поток однопальцевых. Для начала объясню, что было сложного.


Первое и третье правила я постиг за первые 10 минут анализа логов (кстати, это один из тех случаев, когда надо отправить debug туда, где ему и место) и с ними все было пучком. Я написал свой GestureDetector и начал тестировать. Когда тестирование перешло с режима предсказуемых действий в режим обезьяна (случайные движения по перестукиванию пальцами или их скольжению по поверхность) мой компонент с радостным криком грохнулся. После я раскуривал логи еще часа 3, пока до меня не дошло, что мне реально приходит событие от нового пальца, где-то, в середине списка уже зарегистрированных. Это было очень неприятным открытием. Но оно случилось и теперь вы тоже о нем знаете.


Алгоритм, конечно, кажется простым, но вот представьте, что вам требуется понять, что пользователь, зажав двумя пальцами углы вашего компонента, третьим проводит по вашему компоненту сверху вниз, и, не отпуская третьего пальца, делает быстрое движение поднятия и опускания одного из первых двух пальцев. Это только кажется эквилибристикой, но на деле, если ваш компонент обрабатывает жесты Scroll или Fling, то такое странное движение может привести к непредсказуемым последствиям, вплоть до падения приложения. И я вам гарантирую, что найдется немало пользователей, которые такое движение сделают, а потом будут считать вас «снежинками» (термин нагло сперт у cartmendum). В общем и целом – будьте внимательны, когда обрабатываете события касаний на Android.

Tags: android, работа
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments