Используйте жесты запястья на Wear

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

Например, пользователь может пролистывать уведомления одной рукой, держа в другой чашку воды. Другие варианты использования жестов на запястье включают следующее:

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

Чтобы просмотреть жесты запястья на часах, убедитесь, что жесты включены, выбрав «Настройки» > «Дополнительные функции» > «Жесты» > «Жесты запястья включены» . Затем завершите обучение жестам на часах, выбрав «Запустить обучение» .

Примечание. Встряхивание запястья является общесистемным жестом возврата или отмены и недоступно для настройки приложений.

Жесты запястьем можно использовать следующими способами, как описано в этом руководстве:

Каждый жест запястья сопоставляется с константой int из класса KeyEvent , как показано в следующей таблице:

Жест Ключевое событие Описание
Выведите запястье наружу KEYCODE_NAVIGATE_NEXT Этот ключевой код переходит к следующему элементу.
Проведите запястьем внутрь KEYCODE_NAVIGATE_PREVIOUS Этот ключевой код переходит к предыдущему пункту.

Используйте изогнутый макет для поддержки жестов запястья.

Класс WearableRecyclerView обеспечивает изогнутый макет списков и автоматически поддерживает жесты запястья. В классе есть предопределенные действия для возникновения жестов запястья, когда представление находится в фокусе. Сведения об использовании класса WearableRecyclerView см. в разделе Создание списков в Wear OS . Также ознакомьтесь с разделом «Рекомендации» данного руководства.

Примечание. Класс WearableRecyclerView заменяет аналогичный устаревший класс в библиотеке поддержки носимых устройств.

Даже если вы используете WearableRecyclerView , вы можете использовать константы из класса KeyEvent . Предопределенные действия можно переопределить, создав подкласс WearableRecyclerView и повторно реализовав обратный вызов onKeyDown() . Это поведение можно полностью отключить с помощью setEnableGestureNavigation(false) . Дополнительные сведения см. в разделе «Обработка действий с клавиатуры» .

Используйте ключевые события напрямую

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

Класс, связанный с взаимодействием с пользователем, например View или Activity и реализующий KeyEvent.Callback , может прослушивать ключевые события, связанные с жестами запястья, так же, как он может быть перечислен в любом другом ключевом событии. Платформа Android вызывает View или Activity , фокусирующееся на ключевых событиях. Для жестов обратный вызов метода onKeyDown() вызывается при возникновении жестов.

Например, приложение может переопределять предопределенные действия в View или Activity , реализующем KeyEvent.Callback , следующим образом:

Котлин

class GesturesActivity : Activity() {

    /* KeyEvent.Callback */
    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        return when (keyCode) {
            KeyEvent.KEYCODE_NAVIGATE_NEXT ->
                // Do something that advances a user View to the next item in an ordered list.
                moveToNextItem()
            KeyEvent.KEYCODE_NAVIGATE_PREVIOUS ->
                // Do something that advances a user View to the previous item in an ordered list.
                moveToPreviousItem()
            else -> {
                // If you did not handle it, let it be handled by the next possible element as determined
                // by the Activity.
                super.onKeyDown(keyCode, event)
            }
        }
    }

    /** Shows the next item in the custom list.  */
    private fun moveToNextItem(): Boolean {
        ...
        // Return true if handled successfully, otherwise return false.
        return false
    }

    /** Shows the previous item in the custom list.  */
    private fun moveToPreviousItem(): Boolean {
        ...
        // Return true if handled successfully, otherwise return false.
        return false
    }
}

Ява

public final class GesturesActivity extends Activity {

 @Override /* KeyEvent.Callback */
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  switch (keyCode) {
   case KeyEvent.KEYCODE_NAVIGATE_NEXT:
    // Do something that advances a user View to the next item in an ordered list.
    return moveToNextItem();
   case KeyEvent.KEYCODE_NAVIGATE_PREVIOUS:
    // Do something that advances a user View to the previous item in an ordered list.
    return moveToPreviousItem();
  }
  // If you did not handle it, let it be handled by the next possible element as determined by the Activity.
  return super.onKeyDown(keyCode, event);
 }

 /** Shows the next item in the custom list. */
 private boolean moveToNextItem() {
  boolean handled = false;
  ...
  // Return true if handled successfully, otherwise return false.
  return handled;
 }

 /** Shows the previous item in the custom list. */
 private boolean moveToPreviousItem() {
  boolean handled = false;
  ...
  // Return true if handled successfully, otherwise return false.
  return handled;
 }
}

Лучшие практики

  • Просмотрите страницы KeyEvent и KeyEvent.Callback для доставки ключевых событий в ваше View и Activity .
  • Сохраняйте постоянную возможность направления: используйте «вывести запястье наружу» для следующего и «провести запястье внутрь» для предыдущего.
  • Используйте прикосновение, параллельное жесту.
  • Обеспечьте визуальную обратную связь.
  • Не используйте код ключа для реализации функций, которые могут противоречить здравому смыслу остальной части системы. Например, не используйте KEYCODE_NAVIGATE_NEXT для отмены действия или для перемещения по оси лево-право с помощью пролистывания.
  • Не перехватывайте ключевые события на элементах, которые не являются частью пользовательского интерфейса, например представлениях, находящихся за кадром или частично скрытых. Это то же самое, что и для любого ключевого события.
  • Не интерпретируйте повторяющиеся жесты перелистывания в свой собственный новый жест. Это может конфликтовать с системным жестом «встряхивания запястья».
  • Чтобы представление могло получать события клавиш жестов, оно должно иметь фокус ; см. View.setFocusable() .

    Поскольку жесты рассматриваются как ключевые события, они вызывают переход из «режима касания», который может привести к неожиданным последствиям. Поскольку пользователи могут поочередно использовать сенсорное управление и жесты, может потребоваться метод View::setFocusableInTouchmode() . В некоторых случаях также может потребоваться использовать setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS) чтобы при изменении фокуса после перехода в сенсорный режим или из него фокус получал предполагаемое представление.

  • Используйте requestFocus() clearFocus() осторожно:
    • При вызове requestFocus() убедитесь, что представление имеет фокус. Если представление находится за кадром или закрыто другим представлением, могут возникнуть неожиданности, когда жесты запускают обратные вызовы.
    • Метод clearFocus() инициирует поиск фокуса, чтобы найти другое подходящее представление. В зависимости от иерархии представлений этот поиск может потребовать нетривиальных вычислений. Это также может привести к присвоению фокуса представлению, которое вы не ожидаете получить.
  • Ключевые события сначала доставляются в представление с фокусом в иерархии представлений. Если представление с фокусом не обрабатывает событие — другими словами, оно возвращает false — событие не доставляется родительскому представлению, даже если оно может получать фокус и имеет KeyListener . Скорее, событие доставляется текущему действию, удерживая в фокусе иерархию представлений.

    Поэтому может потребоваться перехватить все события на более высоком уровне, а затем передать соответствующие коды вниз. В качестве альтернативы вы можете создать подкласс действия и переопределить метод dispatchKeyEvent(KeyEvent event) чтобы перехватывать ключи, когда это необходимо, или обрабатывать их, когда они не обрабатываются на нижних уровнях.