?

Log in

No account? Create an account

Предыдущая версия | Обновление

Сегодня будет первая часть моего эпоса о том, как все прекрасно в мире обработки пользовательского ввода на 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.

История версий

Октябрь 2015
Вс Пн Вт Ср Чт Пт Сб
    123
45678910
11121314151617
18192021222324
25262728293031
Разработано LiveJournal.com
Designed by Katy Towell