События ввода

В Android есть несколько способов перехватить события пользователя. Cобытия перехватываются у объектов типа View, с которыми взаимодействует пользователь, а класс View предоставляет необходимые для этого средства.

Подклассы View, содержат методы обратного вызова, которые удобно использовать для обработки событий пользовательского интерфейса. Эти методы вызываются системой, когда происходит соответствующее действие с объектом. Например, когда пользователь нажимает кнопку, вызывается метод onTouchEvent() для данной кнопки. Чтобы обработать событие, необходимо расширить класс нужного объекта и переопределить метод, однако делать это для каждого из существующих объектов не практично. Поэтому класс View содержит также набор вложенных интерфейсов с методами обратного вызова, которые гораздо проще использовать. Данные интерфейсы называются слушателями событий.

Слушатели событий

Слушатель это вложенный интерфейс класса View, включающий в себя единственный метод обратного вызова. Этот метод вызывается системой Android, когда пользователь взаимодействует с объектом типа View, для которого зарегистрирован слушатель.

Слушатели включают в себя следующие методы:

onClick()
Интерфейс View.OnClickListener. Вызывается, когда пользователь касается объекта или наводит на него фокус (при использовании трекболла, джойстика или клавиатуры) и нажимает “ввод”.
onLongClick()
Интерфейс View.OnLongClickListener. Вызывается, когда пользователь касается объекта и удерживает его, либо наводит на него фокус и держит “ввод” в течение некоторого времени.
onFocusChange()
Интерфейс View.OnFocusChangeListener. Вызывается, когда пользователь перемещает фокус на другой объект (при использовании трекболла, джойстика или клавиатуры).
onKey()
Интерфейс View.OnKeyListener. Вызывается, когда пользователь нажимает или отпускает аппаратную клавишу на устройстве.
onTouch()
Интерфейс View.OnTouchListener. Вызывается, когда пользователь выполняет операции с сенсором, в том числе нажатие, отпускание или какой-либо жест (в пределах границ объекта).
onCreateContextMenu()
Интерфейс View.OnCreateContextMenuListener. Вызывается при создании контекстного меню (например в результате длинного нажатия). Подробнее обсуждается в разделе Меню.

Эти методы являются единственными членами соответствующих интерфейсов. Для реализации методов и обработки событий, создайте вложенный интерфейс в коде явления или определите его в качестве анонимного класса. Затем передайте созданный экземпляр в соответствующий метод View.set.....Listener() (например setOnClickListener()).

Пример обработки нажатия на кнопку:

Иногда удобно реализовать OnClickListener как часть явления. Это позволяет избежать дополнительной загрузки классов и распределения объектов. Например:

Помните, что в примере выше метод onClick() не возвращает значений, но существуют некоторые другие методы, которые могут возвращать тип boolean. Это зависит от события, и вот почему:

  • onLongClick() – возвращает boolean, который показывает, продолжать ли обработку касания. Если метод возвращает “true”, дальнейшие действия не выполняются. Если метод возвращает “false”, продолжится поиск других слушателей для события on-click.
  • onKey() – возвращает boolean, который показывает, продолжать ли обработку нажатия на кнопку. Если метод возвращает “true”, дальнейший действия не выполняются. Если метод возвращает “false”, продолжится поиск других слушателей для события on-key.
  • onTouch() – важно понимать, что это событие может иметь несколько действий, которые следуют друг за другом. Так, если метод возвращает “false” при получении события нажатия, это означает, что вы не обрабатываете событие в данном методе, а также не желаете обрабатывать последующие связанные события. То есть метод не будет вызываться для любых других действий в рамках текущего события, таких как жесты или отпускание.

Помните, что события нажатия аппаратных клавиш всегда передаются объекту View, который в текущий момент имеет фокус. События движутся сверху вниз по дереву объектов View, пока не достигнут назначения. Так если ваш объект View (или дочерний элемент вашего View) имеет фокус, вы можете наблюдать как перемещается событие с помощью метода dispatchKeyEvent(). Вы также можете захватывать все события работы с аппаратными кнопками в классе явления, используя методы onKeyDown() и onKeyUp().

Кроме того, когда вы размышляете о вводе текста в приложение, помните, что многие устройства имеют только программные методы ввода. Некоторые методы не могут использовать события on-key, например голосовой ввод или распознавание почерка и так далее. Даже если метод ввода представляет из себя интерфейс клавиатуры, обычно он не генерирует событие onKeyDown(). Поэтому никогда не проектируйте интерфейс, который требует нажатий клавиш, только если не хотите ограничить приложение для устройств с аппаратной клавиатурой. В частности, не полагайтесь на эти методы, чтобы отследить нажатие клавиши возврата. Вместо этого используйте действия, вроде IME_ACTION_DOWN.

Примечание: Android вызывает сначала ваш обработчик события, а затем соответствующий обработчик по умолчанию, который содержит класс. Если обработчик события возвращает “true”, распространение события на других слушателей будет остановлено, а также заблокирован метод обратного вызова по умолчанию. Так что убедитесь, что действительно хотите прервать распространение события, если возвращаете “true” из вашего обработчика.

Обработка событий

Если вы создаете собственный компонент на основе класса View, то сможете определить несколько методов обратного вызова, которые используются как обработчики событий по умолчанию. В разделе Собственные компоненты вы найдете описание некоторых распространенных методов, в том числе:

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

Режим касания (Touch Mode)

Когда пользователь использует трекболл или джойстик, необходимо передавать фокус на элементы, которые реагируют на нажатие (например кнопки), чтобы пользователь видел какой элемент в текущий момент принимает ввод. Однако, если устройство имеет сенсорный экран и пользователь использует его для взаимодействия с приложением, нет необходимости подсвечивать текущий элемент или передавать фокус от элемента к элементу. Такой режим взаимодействия называется “режим касания”.

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

Как только пользователь воспользуется аппаратными клавишами или трекболлом, устройство выходит из режима касания и ищет элемент, который примет фокус.

Режим касания поддерживается всеми элементами системы (все окна и явления). Для запроса текущего режима используйте метод isInTouchMode(), который возвращает true, если устройство находится в режиме касания.

Работа с фокусом

Система перемещает текущий фокус в ответ на действия пользователя. Сюда входит изменение фокуса при удалении или скрытии элемента или при добавлении нового. Элементы показывают готовность принять фокус с помощью метода isFocusable(), а в режиме касания с помощью метода isFocusableInTouchMode(). Чтобы установить способность элемента принимать фокус, используется метод setFocusable(). Для разрешения или запрета принимать фокус в режиме касания существует метод setFocusableInTouchMode().

Перемещение фокуса основано на поиске ближайшего соседа в заданном направлении. В редких случаях, работа алгоритма по умолчанию может не соответствовать ожиданиям разработчика. В такой ситуации вы можете явно переопределить поведение с помощью соответствующих XML атрибутов в файле разметки: nextFocusDown, nextFocusLeft, nextFocusRight и nextFocusUp. Добавьте один из этих атрибутов элементу, из которого фокус переходит к другому. В качестве значения атрибута должен быть указан идентификатор элемента, которому фокус должен быть передан. Например:

В такой вертикальной разметке некуда перемещать фокус от первой кнопки вверх, а также от второй кнопки вниз. В приведенном примере фокус будет переходить циклически от верхней кнопки к нижней, а от нижней кнопки – к верхней.

Если вы хотите указать, что элемент может получить фокус, добавьте ему атрибут android:focusable=true. Вы можете также указать, что элемент может получить фокус в режиме касания с помощью атрибута android:focusableInTouchMode.

Чтобы установить фокус элементу, вызовите метод requestFocus().

Чтобы отслеживать события фокуса (если элемент получает или теряет фокус), используйте метод onFocusChange(), как описано выше.

Добавить комментарий