Руководство по жестам в Android для разработчиков (Android 10)
Стандартные компоненты пользовательского интерфейса Android по умолчанию поддерживают ряд жестов Android, но иногда вашему приложению может потребоваться поддержка большего, чем просто onClick!
В этом руководстве по жестам Android мы рассмотрим все, что вам нужно для реализации ряда жестов Android. Мы будем создавать ряд простых приложений, которые обеспечат понимание основных концепций сенсорных жестов, включая то, как Android записывает «жизненный цикл» жеста и как он отслеживает движение отдельных пальцев при взаимодействии с несколькими касаниями.
Иногда ваше приложение может нуждаться в поддержке не только onClick.
Чтобы продемонстрировать, как эта информация может быть преобразована в реальные проекты, мы также создадим приложение, которое позволяет пользователю увеличивать и уменьшать масштаб изображения с помощью жеста сжатия. Наконец, поскольку Android 10 готов полностью пересмотреть поддержку жестов Android, мы рассмотрим, как вы можете обновить свои приложения для поддержки новой навигации на основе жестов Android, в том числе как убедиться, что собственные жесты вашего приложения не конфликтуют с Android 10. общесистемные жесты.
Читайте также: Создание пользовательского интерфейса Android: все, что вам нужно знать о представлениях
Что такое сенсорные жесты?
Сенсорные жесты позволяют пользователям взаимодействовать с вашим приложением с помощью прикосновений.
Android поддерживает ряд сенсорных жестов, в том числе касание, двойное касание, сжатие, пролистывание, прокрутку, долгое нажатие, перетаскивание и бросок. Хотя перетаскивание и бросок похожи, перетаскивание – это тип прокрутки, который происходит, когда пользователь проводит пальцем по сенсорному экрану, в то время как жест бросания происходит, когда пользователь перетаскивает, а затем быстро поднимает палец.
Навигация с помощью жестов играет важную роль в Android 10, поэтому мы должны быть осторожны, чтобы не вызвать конфликтов при добавлении собственных!
Жесты Android можно разделить на следующие категории:
- Жесты навигации. Они позволяют пользователю перемещаться по вашему приложению и могут использоваться для дополнения других методов ввода, таких как навигационные панели и меню.
- Жесты действий. Как следует из названия, жесты действий позволяют пользователю выполнить действие.
- Трансформируйте жесты. Они позволяют пользователю изменять размер, положение и поворот элемента, например, сжимать, чтобы увеличить изображение или карту.
В Android отдельные пальцы или другие объекты, выполняющие сенсорный жест, называются указателями.
MotionEvents: понимание жизненного цикла жеста
Событие касания начинается, когда пользователь помещает один или несколько указателей на сенсорный экран устройства, и заканчивается, когда они удаляют эти указатели с экрана. Это начинается с жестов Android.
Пока один или несколько указателей контактируют с экраном, объекты MotionEvent собирают информацию о событии касания. Эта информация включает в себя движение события касания в координатах X и Y, а также давление и размер области контакта.
MotionEvent также описывает состояние события касания с помощью кода действия. Android поддерживает длинный список кодов действий, но некоторые из основных кодов действий включают:
- ACTION_DOWN. Событие касания началось. Это место, где указатель впервые соприкасается с экраном.
- ACTION_MOVE. Произошло изменение во время события касания (между ACTION_DOWN и ACTION_UP). ACTION_MOVE содержит самые последние координаты указателя X и Y, а также любые промежуточные точки с момента последнего события DOWN или MOVE.
- ACTION_UP. Событие касания завершено. Он содержит место финального релиза. Предполагая, что жест не отменен, все события касания завершаются ACTION_UP.
- ACTION_CANCEL. Жест был отменен, и Android не получит дополнительной информации об этом событии. Вы должны обрабатывать ACTION_CANCEL точно так же, как обрабатываете событие ACTION_UP.
Объекты MotionEvent передают код действия и значения оси методу обратного вызова события onTouchBack() для представления, получившего это событие касания. Вы можете использовать эту информацию, чтобы интерпретировать шаблон сенсорного жеста и соответствующим образом отреагировать. Обратите внимание, что каждый объект MotionEvent будет содержать информацию обо всех указателях, которые в настоящее время активны, даже если эти указатели не перемещались с момента доставки предыдущего MotionEvent.
Хотя Android действительно пытается доставить согласованный поток событий MotionEvents, событие может быть отброшено или изменено до того, как оно будет успешно доставлено. Чтобы обеспечить удобство взаимодействия с пользователем, ваше приложение должно уметь обрабатывать несовместимые события MotionEvents, например, если оно получает событие ACTION_DOWN, не получая ACTION_UP для «предыдущего» жеста. Это важное соображение в нашем руководстве по жестам Android.
Чтобы проиллюстрировать «жизненный цикл» сенсорного жеста, давайте создадим приложение, которое извлекает код действия для каждого объекта MotionEvent и затем выводит эту информацию в Logcat Android Studio.
В следующем коде мы перехватываем каждое событие касания, переопределяя метод onTouchEvent (), а затем проверяем следующие значения:
- Верно. Наше приложение обработало это событие касания, и мы должны вывести соответствующее сообщение в Logcat.
- Ложные. Наше приложение не обработало это событие касания. Событие будет продолжать проходить через стек, пока onTouchEvent не вернет true.
Метод onTouchEvent () будет запускаться каждый раз при изменении положения указателя, давления или площади контакта.
В следующем коде я также использую getActionMasked () для получения выполняемого действия:
import
Установите это приложение на свой физический смартфон или планшет Android и экспериментируйте, выполняя различные сенсорные жесты. Android Studio должна выводить в Logcat разные сообщения в зависимости от того, на каком этапе жизненного цикла сенсорного жеста вы находитесь.
OnTouchListener: захват событий касания для определенных представлений
Вы также можете прослушивать события касания, используя метод setOnTouchListener () для присоединения View.OnTouchListener к вашему объекту View. Метод setOnTouchListener () регистрирует обратный вызов, который будет вызываться каждый раз, когда событие касания отправляется в присоединенный View, например, здесь мы вызываем обратный вызов каждый раз, когда пользователь касается ImageView:
View imageView = findViewById(R.id.my_imageView);
myView.setOnTouchListener(
Обратите внимание, что если вы используете View.OnTouchListener, вам не следует создавать прослушиватель, который возвращает false для события ACTION_DOWN. Поскольку ACTION_DOWN является отправной точкой для всех событий касания, значение false приведет к тому, что ваше приложение застрянет на ACTION_DOWN, и слушатель не будет вызываться для любых последующих событий.
Touch slop: запись жестов на основе движения
Сенсорные жесты не всегда точны! Например, ваш палец легко может немного сдвинуться, когда вы просто пытаетесь нажать кнопку, особенно если вы используете свой смартфон или планшет в дороге или у вас проблемы с маневренностью.
Чтобы предотвратить случайную прокрутку, жесты Android используют концепцию «касания», которая представляет собой расстояние в пикселях, на которое может перемещаться указатель, прежде чем жест без движения, такой как касание, станет жестом на основе движения, например как тормоз.
Наклон касания – это расстояние в пикселях, на которое может пройти указатель, прежде чем жест без движения.
При использовании жестов на основе движения необходимо убедиться, что пользователь контролирует любое происходящее на экране движение. Например, если пользователь перетаскивает объект по экрану, скорость перемещения этого объекта должна соответствовать скорости жеста пользователя.
Вы можете измерить скорость жеста, основанного на движении, с помощью класса Android VelocityTracker. В следующем упражнении я использую VelocityTracker для получения скорости жеста, а затем распечатываю скорость в Logcat Android Studio:
import
Установите это приложение на свое устройство Android и экспериментируйте, выполняя различные жесты, основанные на движении; скорость каждого жеста должна быть напечатана в окне Logcat.
GestureDetector: создание приложения для масштабирования пальцем с помощью жестов Android
Предполагая, что вы используете обычные жесты Android, такие как касание и долгое нажатие, вы можете использовать класс Android GestureDetector для обнаружения жестов без необходимости обрабатывать отдельные события касания.
Чтобы обнаружить жест, вам нужно создать экземпляр GestureDetector, а затем вызвать onTouchEvent (android.view.MotionEvent) в методе View # onTouchEvent (MotionEvent). Затем вы можете определить, как должно обрабатываться это событие касания, в обратном вызове.
Читайте также: Изучение Android Q: Добавление пузырьковых уведомлений в ваше приложение
Давайте создадим приложение, в котором пользователь может увеличивать и уменьшать изображение ImageView с помощью жестов. Для начала создайте простой макет, содержащий изображение:
<?xml version="1.0" encoding="utf-8"?>
Чтобы создать эффект увеличения / уменьшения масштаба, я использую ScaleGestureDetector, удобный класс, который может прослушивать подмножество событий масштабирования, а также вспомогательный класс SimpleOnScaleGestureListener.
В следующем действии я создаю экземпляр ScaleGestureDetector для своего ImageView, а затем вызываю onTouchEvent (android.view.MotionEvent) в методе View # onTouchEvent (Motionvent). Наконец, я определяю, как приложение должно обрабатывать этот жест.
import
Попробуйте установить это приложение на физический смартфон или планшет Android, и вы сможете сжимать и расширять выбранное изображение, используя жесты сжимания и сжимания.
Управление мультитач-жестами
Некоторые жесты требуют использования нескольких указателей, например жест щипка. Каждый раз, когда несколько указателей соприкасаются с экраном, Android генерирует:
- Событие ACTION_DOWN для первого указателя, касающегося экрана.
- ACTION_POINTER_DOWN для всех последующих, неосновных указателей, которые контактируют с экраном.
- ACTION_POINTER_UP, когда неосновной указатель удаляется с экрана.
- Событие ACTION_UP, когда последний указатель разрывает контакт с экраном.
Например, в следующем упражнении я определяю, является ли жест однократным или мультитач, а затем распечатываю соответствующее сообщение в Logcat Android Studio. Я также печатаю код действия для каждого события и координаты X и Y для каждого указателя, чтобы лучше понять, как Android отслеживает отдельные указатели:
import
Управление жестами в ViewGroups
При обработке сенсорных событий в ViewGroup возможно, что ViewGroup может иметь дочерние элементы, которые являются целями для других сенсорных событий, чем родительская ViewGroup.
Чтобы каждый дочерний View получал правильные события касания, вам необходимо переопределить метод onInterceptTouchEvent (). Этот метод вызывается каждый раз, когда событие касания обнаруживается на поверхности ViewGroup, что позволяет перехватить событие касания до того, как оно будет отправлено дочерним представлениям.
Также прочитайте:
Если метод onInterceptTouchEvent () возвращает true, тогда дочернее представление, которое ранее обрабатывало событие касания, получит ACTION_CANCEL, и это событие будет отправлено вместо этого родительскому методу onTouchEvent ().
Например, в следующем фрагменте мы решаем, следует ли перехватывать событие касания, в зависимости от того, является ли оно событием прокрутки:
Запустите это приложение на своем устройстве Android, и результат Logcat должен выглядеть примерно так:
Сделайте свое приложение легкой мишенью: расширение доступных областей
Вы можете упростить взаимодействие с небольшими элементами пользовательского интерфейса, увеличив размер области, доступной для осязания, которую иногда называют прямоугольником попадания. В качестве альтернативы, если ваш пользовательский интерфейс содержит несколько интерактивных элементов пользовательского интерфейса, вы можете уменьшить их достижимые цели, чтобы предотвратить запуск пользователями «неправильного» представления.
Вы можете настроить размер сенсорной области дочернего View с помощью класса TouchDelegate.
Давайте создадим кнопку, а затем посмотрим, как мы расширим доступную для прикосновения область этой кнопки.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
Чтобы изменить доступную область просмотра, нам нужно выполнить следующие шаги:
1. Получите родительский View и опубликуйте Runnable в потоке пользовательского интерфейса.
Прежде чем мы вызовем метод getHitRect () и получим доступную для прикосновения область дочернего элемента, мы должны убедиться, что родитель разместил свои дочерние представления:
parentView.post(
2. Определите границы зоны прикосновения ребенка.
Мы можем получить текущую доступную для прикосновения цель кнопки, используя метод getHitRect ():
Rect delegateArea =
3. Расширьте границы области прикосновения.
Здесь мы увеличиваем область касания кнопки в нижней и правой частях:
delegateArea.right += 400;
delegateArea.bottom += 400;
4. Создайте экземпляр TouchDelegate.
Наконец, нам нужно передать расширенную цель касания в экземпляр класса Android TouchDelegate:
TouchDelegate touchDelegate =
Вот наша завершенная MainActivity:
import
Установите этот проект на вашем Android устройства и попробуйте нажав вокруг правой и нижнюю части кнопки – так как мы расширили осязаемую площадь значительного количества, тост должен появиться, когда вы нажмете где – нибудь рядом с кнопкой.
Начиная с уровня API 29, Android поддерживает полную навигацию на основе жестов.
Пользователи последней и лучшей версии Android смогут запускать следующие действия, используя только жесты:
- Назад. Проведите внутрь от левого или правого края экрана.
- Дом. Проведите вверх от нижней части экрана.
- Запустить Ассистент. Проведите от нижнего угла экрана.
Android 10 по-прежнему будет поддерживать традиционную трехкнопочную навигацию, поэтому у пользователей будет возможность вернуться к кнопочной навигации, если они захотят.
Согласно Google, навигация на основе жестов будет по умолчанию для Android 10 и выше, поэтому вам необходимо убедиться, что ваше приложение обеспечивает хорошее взаимодействие с пользователем с новой моделью Android на основе жестов.
Сделайте свой пользовательский интерфейс от края до края
Навигация на основе жестов делает большую часть экрана доступной для вашего приложения, поэтому вы можете обеспечить более захватывающий опыт, расширив контент вашего приложения от края до края.
По умолчанию приложения размещаются под строкой состояния и над панелью навигации (вместе именуемые системными панелями). При отображении от края до края ваше приложение размещается за панелью навигации и, возможно, за системной панелью, если это имеет смысл для вашего конкретного приложения.
Вы можете указать системе разместить ваше приложение за системной панелью, используя метод View.setSystemUiVisibility () и флаги SYSTEM_UI_FLAG_LAYOUT_STABLE и SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION. Например:
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
Обратите внимание, что если вы используете класс View, который автоматически управляет строкой состояния, например CoordinatorLayout, эти флаги могут быть уже установлены.
Как сделать системную панель прозрачной
После того, как ваше приложение отображается от края до края, вам необходимо убедиться, что пользователь может видеть содержимое вашего приложения за системными панелями.
Чтобы сделать системные панели полностью прозрачными, добавьте в свою тему следующее:
<style name=
Android 10 автоматически изменит цвет системной панели в зависимости от содержимого, стоящего за ней, в процессе, известном как динамическая адаптация цвета, поэтому вам не нужно беспокоиться о внесении этих настроек вручную.
Проверьте наличие противоречивых жестов
Вам нужно будет проверить, что новая система навигации Android на основе жестов не конфликтует с существующими жестами вашего приложения.
В частности, вы должны убедиться, что жест «Назад» (смахивание внутрь от левого или правого края экрана) не запускает какие-либо интерактивные элементы вашего приложения. Например, если в вашем приложении есть панель навигации в левой части экрана, то каждый раз, когда пользователь пытается перетащить этот ящик, он запускает жест «Назад» Android и может завершиться выходом из вашего приложения.
Если тестирование выявляет конфликты жестов, вы можете предоставить список областей в своем приложении, где система не должна интерпретировать события касания как жесты возврата.
Чтобы предоставить этот список исключений, передайте List в новый метод Android View.setSystemGestureExclusionRects (), например:
List exclusionRects;
Обратите внимание, что вы должны отключать жест «Назад» только для видов, для которых требуется точный жест в пределах небольшой области, а не для широких областей или простых целей касания, таких как кнопки.
А как насчет жеста Android 10 Home?
На момент написания статьи невозможно отказаться от жеста «Домой» в Android 10 (смахивание вверх от нижней части экрана). Если у вас возникли проблемы с жестом «Домой», то одним из возможных способов решения этой проблемы является установка пороговых значений распознавания касаний с помощью [WindowInsets.getMandatorySystemGestureInsets ()](https://developer.android.com/reference/android/view/WindowInsets.html#getMandatorySystemGestureInsets()) .
Некоторые приложения, такие как мобильные игры, не имеют иерархии представлений, но могут по-прежнему требовать от пользователя выполнения жестов в областях, которые запускают систему навигации Android на основе жестов.
Если в игровом приложении возникают конфликты жестов, используйте метод Window.setSystemGestureExclusionRects (), чтобы предоставить список областей, в которых система не должна интерпретировать события касания как жесты возврата.
В качестве альтернативы вы можете запросить, чтобы ваше приложение было размещено в иммерсивном режиме, который отключает все системные жесты.
Вы можете включить иммерсивный режим, вызвав setSystemUiVisibility () и передав следующие флаги:
- SYSTEM_UI_FLAG_FULLSCREEN. Все некритические элементы системы будут скрыты, что позволит содержимому вашего приложения занять весь экран.
- SYSTEM_UI_FLAG_HIDE_NAVIGATION. Временно скрыть системную навигацию.
- SYSTEM_UI_FLAG_IMMERSIVE. Это представление должно оставаться интерактивным, когда строка состояния скрыта. Обратите внимание, что для того, чтобы этот флаг имел какой-либо эффект, он должен использоваться в сочетании с SYSTEM_UI_FLAG_HIDE_NAVIGATION.
В иммерсивном режиме пользователь может повторно включить системные жесты в любой момент, проведя пальцем снизу экрана.
Рекомендации: эффективное использование жестов
Теперь мы увидели, как реализовать различные сенсорные жесты, и шаги, которые вы можете предпринять, чтобы подготовить свое приложение к новой системе навигации Android на основе жестов. Давайте рассмотрим некоторые передовые практики, которые помогут вам эффективно использовать жесты.
Не позволяйте пользователям гадать: выделяйте интерактивные компоненты
Если вы используете стандартные представления, то в большинстве случаев ваши пользователи должны автоматически идентифицировать интерактивные компоненты вашего приложения и понимать, как с ними взаимодействовать. Например, если пользователь видит кнопку, он сразу же узнает, что должен нажать на эту кнопку. Однако иногда может быть неясно, является ли конкретное представление интерактивным, и в этих случаях вам нужно будет предоставить им некоторые дополнительные визуальные подсказки.
Есть несколько способов привлечь внимание к интерактивным представлениям вашего приложения. Во-первых, вы можете добавить короткую анимацию, такую как эффект пульсации, или поднять вид, например, поднять карточку, которую пользователь может перетащить на экран, чтобы развернуть.
В качестве альтернативы вы могли бы быть более явным и использовать значки, такие как стрелка, указывающая на представление, с которым пользователю нужно взаимодействовать дальше.
Для более сложных взаимодействий вы можете создать короткую анимацию, которая демонстрирует, как пользователь должен взаимодействовать с представлением, например, анимируя карточку, чтобы она частично скользила по экрану, а затем обратно.
Используйте анимацию для трансформирующих жестов
Когда пользователь выполняет трансформирующий жест, все затронутые элементы пользовательского интерфейса должны анимироваться таким образом, чтобы указывать на то, что произойдет, когда этот жест будет завершен. Например, если пользователь сжимает изображение, чтобы уменьшить изображение, изображение должно уменьшаться в размере, пока пользователь выполняет этот жест, вместо «привязки» к новому размеру после завершения жеста.
Предоставление визуальных подсказок для выполняемых действий
Для жестов, которые выполняют действия, вы должны сообщить действие, которое этот жест будет выполнять после его завершения. Например, когда вы начинаете перетаскивать электронное письмо в приложении Gmail, появляется значок «Архив», указывающий на то, что это электронное письмо будет заархивировано, если вы продолжите перетаскивание.
Указывая на завершенное действие, когда пользователь выполняет жест действия, вы даете ему возможность прервать жест, если результат не соответствует их ожиданиям.
Завершение этого руководства по жестам Android
В этой статье я показал вам, как реализовать различные жесты в ваших приложениях Android и как получить информацию о выполняемых жестах, включая скорость жеста и наличие нескольких указателей. Мы также рассмотрели новую систему навигации Android 10 на основе жестов и шаги, которые вы можете предпринять, чтобы ваше приложение было готово к этому огромному пересмотру того, как пользователи взаимодействуют со своими устройствами Android.
Есть ли у вас какие-либо рекомендации по использованию жестов Android в вашем приложении? Дайте нам знать в комментариях ниже!
Источник записи: https://www.androidauthority.com