Как стать автором
Обновить

Комментарии 20

А зачем в последнем блоке кода использовать switch, если можно обойтись массивом int[] colors?
Почему-то не подумал об этом. Спасибо.
Такой android…
А зачем нужен класс Finger и массив пальцев?
Обычный MotionEvent, который Вы получается в OnTouchEvent содержит в себе методы:
e.getPointerCount() — количество касаний сейчас.
e.getX(), e.getY() — координаты текущего события
e.getX(int position) — координаты произвольного касания
e.getHistoricalX(int position) — получить координату Х для предыдущих состояний.
e.getHistorySize() — размер истории
и т.д.
А еще для распознавания всякий долгих касаний и другихз жестов есть GestureDetector:
developer.android.com/reference/android/view/GestureDetector.html
тут примерчик:
www.androidsnippets.com/gesturedetector-and-gesturedetectorongesturelistener
GestureDetector я использовал. Он будет вызываться даже если палец будет постоянно перемещаться (что в случае с графическим редактором — неправильно).
Про историю касаний (getHistoricalX, getHistoricalY, getHistorySize) я, к сожалению, узнал только что. Сейчас по-быстрому перепишу приложение, используя её, а не класс Finger. Спасибо.
Опробовал историю. При таскании холста есть небольшая погрешность. При рисовании это видно ещё лучше (пример).
Любопытно, на досуге посмотрю сам. Мне казалось, что туда попадают все события.
Туда ни MOVE, ни DOWN, ни UP не попадают. История, видимо, предназначена тут для другого. В ней хранятся точки, находящиеся между двумя событиями MOVE. Если мы очень быстро рисуем кривую (настолько быстро, что вызвалось всего 2 события MOVE), то при втором вызове этого события в качестве истории касаний мы получим промежуточные точки. Тут изобразил пример. Чёрные точки и полоса — то, что предлагает нам событие MOVE. Красные точки — история касаний при событии №2. Красная линия — то, как мы на самом деле касались экрана.
История событий действительно может нам помочь, ведь с её помощью можно сделать редактор (или любое другое приложение) ещё точнее, если это необходимо.
Так делать нельзя:
Override
protected void onDraw(Canvas canvas) {
invalidate();
}

в onDraw нужно только нарисовать вьюшку на канве и все. Вызывая invalidate вы постоянно заставляете перерисовываться вьюшку, даже если ей этого и не надо. Invalidate нужно вызывать из других мест, когды вы хотите, чтобы вид обновился. Вызов Invalidate, в свою очередь, запланирует перерисовку вьюшки.

Можно немного оптимизировать:
Чтобы ловить лонг пресы используется обычно Runnable и функция postDelayed(Runnable, время_долгого_нажатия) Handler'а. Из Runnable, когда он будет выполнятся, нужно будет посмотреть, если палец никуда не двинулся — значит лонг прес. Жалко таймер постоянно крутить )
Вызов invalidate после checkGestures, мне кажется, будет самым лучшим вариантом.
Из Runnable можно просто выполнять то, что выполнялось в таймере. Проверка сдвига пальца от старта осуществляется в методе setNow класса Finger.
Спасибо за статью.
Небольшие придирки:
1. «в качестве Minimum Required SDK можно поставить API 8 (Android 2.2)»
<activity
    android:name=".MainActivity"
    android:label="@string/title_activity_main"
    android:screenOrientation="landscape"
    android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen">

если память не изменяет, то holo чуть позже появился.

2. метод setNow по идеи можно сразу чуть улучшить, поместив код после if в else?
3.в конструкторе density почему-то не проинициализировано.

может еще что упустил, голова под вечер плохо соображает)
Ну и собственно приветствую на хабре.)
Спасибо за замечания, поправил. Хорошо сообразили. :)
Не за что. Если завтра на работе не сильно окопаюсь, постараюсь поглядеть на гитхабе..)

[придирка мод]
android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen">

вроде DeviceDefault еще позже появился, т.к. на 2.2 по умолчанию actionbara нету, то из названия константы идут сомнения...)
Там по идеи лучше через ресурсы делать с модификаторами версии api)
[/придирка мод]
Holo появился с api 11
Theme.DeviceDefault — с api 14.

Соответственно надо это все обернуть в свой стиль и раскидать по values-v11 и values-v14
Изменил, предусмотрев все API. Спасибо.
Спасибо за статью! Методом тыка я узнал, что мультитач не поддерживает больше 10 касаний.
Это зависит от вашего девайса. На моём Samsung Galaxy Nexus, например, тоже 10 касаний. SGS+ — 5 касаний, Sony Ericsson Xperia Arc S — 4 касания.
Да, вы правы. Сейчас поигрался с разными устройствами дома.

Samsung Galaxy Tab 10.1 — 10 касаний, 10 кругов, 11й не добавляется.
Samsung SII — 10 касаний, 10 кругов, одинадцатое касание добавляет новый круг, но удаляет один из существующих, т.е. каждое новое касание добавляет еще один Finger, но удаляет какой-то предыдущий.
Samsung SII LTE — то же самое, что и SII.
Samsung Note — 8 касаний, при девятом приложение виснет, через 15 секунд активити выкидывает ошибку и вылетает.

Буду знать.
Хм… Посмотрите в логах ошибок на Samsung Note, почему выкидывает из приложения? Я считаю, надо учитывать такое.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории