Совместимость ввода на больших экранах

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

  • Проверьте поддержку базовых клавиш , таких как Ctrl+Z для отмены действия, Ctrl+C для копирования и Ctrl+S для сохранения. Список стандартных сочетаний клавиш см. в разделе « Обработка действий с клавиатуры ».
  • Проверьте расширенную поддержку клавиатуры , например, навигацию с помощью клавиши Tab и клавиш со стрелками, подтверждение ввода текста клавишей Enter , а также воспроизведение и паузу с помощью пробела в мультимедийных приложениях.
  • Протестируйте основные взаимодействия с мышью , включая щелчок правой кнопкой мыши для вызова контекстного меню, изменение значков при наведении курсора, а также события прокрутки колесиком мыши или трекпадом для пользовательских компонентов.
  • Протестируйте устройства ввода, специфичные для конкретного приложения, такие как стилус, игровые контроллеры и MIDI-контроллеры для музыкальных приложений.
  • Рассмотрите возможность расширения поддержки ввода , которая могла бы выделить приложение в настольных средах, например, использование сенсорной панели в качестве кроссфейдера для диджейских приложений, захват мыши для игр и сочетания клавиш для пользователей, предпочитающих клавиатуру.

Клавиатура

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

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

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

Котлин

yourView.isFocusable = true

Java

yourView.setFocusable(true);

В качестве альтернативы вы можете установить атрибут focusable в файле разметки:

android:focusable="true"

Для получения более подробной информации см. раздел «Обработка фокуса» .

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

Котлин

// Arrow keys
yourView.nextFocusLeftId = R.id.view_to_left
yourView.nextFocusRightId = R.id.view_to_right
yourView.nextFocusTopId = R.id.view_above
yourView.nextFocusBottomId = R.id.view_below
// Tab key
yourView.nextFocusForwardId = R.id.next_view

Java

// Arrow keys
yourView.setNextFocusLeftId(R.id.view_to_left);
yourView.setNextFocusRightId(R.id.view_to_left);
yourView.setNextFocusTopId(R.id.view_to_left);
yourView.setNextFocusBottomId(R.id.view_to_left);
// Tab key
yourView.setNextFocusForwardId(R.id.next_view);

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

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

Нажатия клавиш

Для ввода текста, который обрабатывается виртуальной экранной клавиатурой ( IME ), например, дляEditTextПриложения должны вести себя должным образом на устройствах с большими экранами без дополнительной разработки. Для нажатий клавиш, которые фреймворк не может предусмотреть, приложения должны обрабатывать поведение самостоятельно. Это особенно важно для приложений с пользовательскими представлениями.

В качестве примеров можно привести приложения для чата, использующие клавишу Enter для отправки сообщения, медиаприложения, запускающие и останавливающие воспроизведение с помощью пробела , и игры, в которых управление движением осуществляется клавишами w , a , s и d .

В большинстве приложений переопределяется функция обратного вызова onKeyUp() и добавляется ожидаемое поведение для каждого полученного кода клавиши:

Котлин

kotlin override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_ENTER -> { sendChatMessage() true } KeyEvent.KEYCODE_SPACE -> { playOrPauseMedia() true } else -> super.onKeyUp(keyCode, event) } }

Java

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_ENTER) {
        sendMessage();
        return true;
    } else if (KeyEvent.KEYCODE_SPACE){
        playOrPauseMedia();
        return true;
    } else {
        return super.onKeyUp(keyCode, event);
    }
}

Событие onKeyUp происходит при отпускании клавиши. Использование функции обратного вызова предотвращает необходимость обработки приложениями нескольких событий onKeyDown , если клавиша удерживается или медленно отпускается. Игры и приложения, которым необходимо определять момент нажатия клавиши или удерживание клавиши пользователем, могут отслеживать событие onKeyDown и обрабатывать повторяющиеся события onKeyDown самостоятельно.

Для получения дополнительной информации см. раздел «Обработка действий с клавиатуры» .

Ярлыки

При использовании аппаратной клавиатуры ожидаются стандартные сочетания клавиш, включая Ctrl , Alt , Shift и Meta . Если приложение не поддерживает сочетания клавиш, это может вызывать у пользователей разочарование. Опытные пользователи также ценят сочетания клавиш для часто используемых задач, специфичных для приложения. Сочетания клавиш упрощают использование приложения и отличают его от приложений, в которых их нет.

К числу распространенных сочетаний клавиш относятся Ctrl+S (сохранить), Ctrl+Z (отменить) и Ctrl+Shift+Z (повторить). Список стандартных сочетаний клавиш см. в разделе «Обработка действий клавиатуры» .

Сочетания клавиш можно включить, реализовав метод dispatchKeyShortcutEvent() для перехвата всех комбинаций клавиш ( Alt , Ctrl , Shift и Meta ) для заданного кода клавиши. Для проверки наличия определенной клавиши-модификатора используйте:

Котлин

override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean {
  return when (event.keyCode) {
    KeyEvent.KEYCODE_O -> {
      openFile() // Ctrl+O, Shift+O, Alt+O
      true
    }
    KeyEvent.KEYCODE_Z-> {
      if (event.isCtrlPressed) {
        if (event.isShiftPressed) {
          redoLastAction() // Ctrl+Shift+Z pressed
          true
        } else {
          undoLastAction() // Ctrl+Z pressed
          true
        }
      }
    }
    else -> {
      return super.dispatchKeyShortcutEvent(event)
    }
  }
}

Java

@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
  if (event.getKeyCode() == KeyEvent.KEYCODE_O) {
      openFile(); // Ctrl+O, Shift+O, Alt+O
      return true;
  } else if(event.getKeyCode() == KeyEvent.KEYCODE_Z) {
      if (event.isCtrlPressed()) {
          if (event.isShiftPressed()) {
              redoLastAction();
              return true;
          }
          else {
              undoLastAction();
              return true;
          }
      }
  }
  return super.dispatchKeyShortcutEvent(event);
}

Разделение кода обработки сочетаний клавиш от других операций ввода (таких как onKeyUp() и onKeyDown() ) позволяет по умолчанию принимать клавиши-модификаторы без необходимости вручную проверять их каждый раз. Разрешение всех комбинаций клавиш-модификаторов также может быть удобнее для пользователей, привыкших к различным раскладкам клавиатуры и операционным системам.

Однако, вы также можете реализовать сочетания клавиш в onKeyUp() , проверяя наличие KeyEvent.isCtrlPressed() , KeyEvent.isShiftPressed() или KeyEvent.isAltPressed() . Это может упростить поддержку, если изменение поведения клавиш больше связано с поведением приложения, чем с самим сочетанием клавиш. Например, в играх, когда W означает «идти вперед», а Shift+W означает «бежать вперед».

Котлин

override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
  return when(keyCode) {
    KeyEvent.KEYCODE_W-> {
      if (event.isShiftPressed) {
        if (event.isCtrlPressed) {
          flyForward() // Ctrl+Shift+W pressed
          true
        } else {
          runForward() // Shift+W pressed
          true
        }
      } else {
        walkForward() // W pressed
        true
      }
    }
    else -> super.onKeyUp(keyCode, event)
  }
}

Java

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_W) {
        if (event.isShiftPressed()) {
            if (event.isCtrlPressed()) {
                flyForward(); // Ctrl+Shift+W pressed
                return true;
            } else {
                runForward(); // Shift+W pressed
                return true;
            }
        } else {
            walkForward();
            return true;
        }
    }
    return super.onKeyUp(keyCode, event);
}

См. также «Помощник по сочетаниям клавиш» .

Стилус

Многие устройства с большими экранами поставляются со стилусом. Приложения для Android обрабатывают стилусы как сенсорный ввод. Некоторые устройства также могут иметь графический планшет с USB или Bluetooth, например, Wacom Intuos . Приложения для Android могут принимать ввод через Bluetooth, но не через USB.

Событие, связанное со стилусом, регистрируется как событие сенсорного экрана с помощью View#onTouchEvent() или View#onGenericMotionEvent() и содержит вызов MotionEvent#getSource() типа SOURCE_STYLUS .

Объект MotionEvent содержит информацию о событии:

Исторические моменты

Android обрабатывает входные события пакетами и передает их один раз за кадр. Стилус может сообщать о событиях с гораздо большей частотой, чем дисплей. При создании приложений для рисования проверяйте события, которые могли произойти в недавнем прошлом, используя API getHistorical :

Отторжение ладони

Когда пользователи рисуют, пишут или взаимодействуют с вашим приложением с помощью стилуса, они иногда касаются экрана ладонью. Событие касания (установленное на ACTION_DOWN или ACTION_POINTER_DOWN ) может быть передано вашему приложению до того, как система распознает и проигнорирует случайное касание ладонью.

В Android события касания ладони отменяются путем отправки MotionEvent . Если ваше приложение получает ACTION_CANCEL , отмените жест. Если ваше приложение получает ACTION_POINTER_UP , проверьте, установлен ли флаг FLAG_CANCELED . Если да, отмените жест.

Не следует проверять только флаг FLAG_CANCELED . В Android 13 (уровень API 33) и выше система устанавливает FLAG_CANCELED для событий ACTION_CANCEL , но в более ранних версиях Android этот флаг не устанавливается.

Android 12

В Android 12 (уровень API 32) и ниже обнаружение отклонения касания ладонью возможно только для событий касания одним указателем. Если касание ладонью является единственным указателем, система отменяет событие, устанавливая ACTION_CANCEL в объекте события движения. Если нажаты другие указатели, система устанавливает ACTION_POINTER_UP , чего недостаточно для обнаружения отклонения касания ладонью.

Android 13

В Android 13 (уровень API 33) и выше, если единственным указателем является касание ладони, система отменяет событие, устанавливая ACTION_CANCEL и FLAG_CANCELED в объекте события движения. Если нажаты другие указатели, система устанавливает ACTION_POINTER_UP и FLAG_CANCELED .

Всякий раз, когда ваше приложение получает событие движения с ACTION_POINTER_UP , проверяйте наличие атрибута FLAG_CANCELED , чтобы определить, указывает ли событие на отклонение касания ладони (или на отмену другого события).

Приложения для ведения заметок

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

<intent-filter>
    <action android:name="org.chromium.arc.intent.action.CREATE_NOTE" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

После регистрации приложения в системе пользователь может выбрать его в качестве приложения для создания заметок по умолчанию. При запросе новой заметки приложение должно создать пустую заметку, готовую для ввода с помощью стилуса. Когда пользователь хочет добавить аннотацию к изображению (например, к скриншоту или загруженному изображению), приложение запускается с ClipData содержащим один или несколько элементов с URI content:// . Приложение должно создать заметку, используя первое прикрепленное изображение в качестве фонового, и перейти в режим, в котором пользователь может рисовать на экране с помощью стилуса.

Проверьте возможности ведения заметок без стилуса.

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

  1. Переключитесь в режим разработчика и сделайте устройство доступным для записи.
  2. Нажмите Ctrl+Alt+F2, чтобы открыть терминал.
  3. Выполните команду sudo vi /etc/chrome_dev.conf
  4. Нажмите клавишу i для редактирования и добавьте --ash-enable-palette на новую строку в конец файла.
  5. Сохраните файл, нажав клавишу Esc , затем набрав : , w , q и нажав Enter.
  6. Нажмите Ctrl+Alt+F1 , чтобы вернуться к стандартному интерфейсу ChromeOS.
  7. Выйдите из системы, а затем войдите снова.

Теперь на полке должно появиться меню, управляемое стилусом:

  • Нажмите кнопку стилуса на панели инструментов и выберите «Новая заметка» . Откроется пустая заметка для рисования.
  • Сделайте снимок экрана. На панели инструментов выберите кнопку стилуса > Сделать снимок экрана или загрузите изображение. В уведомлении должна появиться опция «Аннотировать изображение» . Это запустит приложение с изображением, готовым к аннотированию.

Поддержка мыши и тачпада

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

Щелчок правой кнопкой мыши

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

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

Котлин

yourView.setOnContextClickListener {
    showContextMenu()
    true
}

Java

yourView.setOnContextClickListener(v -> {
    showContextMenu();
    return true;
});

Подробную информацию о создании контекстных меню см. в разделе «Создание контекстного меню» .

Ховер

Обработка событий наведения курсора может сделать макеты вашего приложения более удобными и привлекательными. Это особенно актуально для пользовательских интерфейсов.просмотров:

Котлин

// Change the icon to a "hand" pointer on hover.
// Highlight the view by changing the background.
yourView.setOnHoverListener { view, _ ->
    addVisualHighlighting(true)
    view.pointerIcon =
        PointerIcon.getSystemIcon(view.context, PointerIcon.TYPE_HAND)
    true // Listener consumes the event.
}

Java

// Change the icon to a "hand" pointer on hover.
// Highlight the view by changing the background.
yourView.setOnHoverListener((view, event) -> {
    addVisualHighlighting(true);
    view.setPointerIcon(
        PointerIcon.getSystemIcon(view.getContext(), PointerIcon.TYPE_HAND)
    );
    return true; // Listener consumes the event.
});

Два наиболее распространенных примера этого:

  • Указывая пользователям на наличие у элемента интерактивного поведения, например, возможности клика или редактирования, путем изменения значка указателя мыши.
  • Добавление визуальной обратной связи к элементам в большом списке или сетке при наведении на них указателя мыши.

Перетаскивание

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

Подумайте, насколько вероятно, что пользователи будут перетаскивать элементы в ваше приложение. Например, фоторедакторы должны ожидать получения фотографий, аудиоплееры — аудиофайлов, а программы для рисования — фотографий.

Для добавления поддержки перетаскивания см.Включить функцию перетаскиванияА также ознакомьтесь с записью в блоге «Android на ChromeOS — реализация функции перетаскивания» .

Особые соображения для ChromeOS

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

Расширенная поддержка указателей

Приложения, которые обеспечивают расширенную обработку ввода с мыши и сенсорной панели, должны реализоватьИспользуйте View#onGenericMotionEvent() и [ MotionEvent.getSource() ][] для различения SOURCE_MOUSE и SOURCE_TOUCHSCREEN .

Изучите объект MotionEvent , чтобы реализовать необходимое поведение:

  • Движение генерирует события ACTION_HOVER_MOVE .
  • Кнопки генерируют события ACTION_BUTTON_PRESS и ACTION_BUTTON_RELEASE . Вы также можете проверить текущее состояние всех кнопок мыши и трекпада с помощью getButtonState() .
  • Прокрутка колесиком мыши генерирует события ACTION_SCROLL .

Игровые контроллеры

Некоторые устройства Android с большими экранами поддерживают до четырех игровых контроллеров. Для работы с игровыми контроллерами используйте стандартные API игровых контроллеров Android (см. раздел «Поддержка игровых контроллеров »).

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

Режим ввода перевода

ChromeOS по умолчанию включает режим преобразования ввода. Для большинства приложений Android этот режим помогает приложениям работать должным образом в среде рабочего стола. Например, он автоматически включает прокрутку двумя пальцами на тачпаде, прокрутку колесиком мыши и сопоставление исходных координат дисплея с координатами окна. Как правило, разработчикам приложений не нужно самостоятельно реализовывать ни одно из этих действий.

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

<uses-feature
    android:name="android.hardware.type.pc"
    android:required="false" />

Дополнительные ресурсы