На устройствах ChromeOS многие пользователи взаимодействуют с приложениями с помощью клавиатуры, мыши, трекпада, стилуса или геймпада. Хотя эти устройства ввода также используются на телефонах Android, они не так распространены и часто игнорируются разработчиками.
Разработчикам, желающим обеспечить корректную работу своего приложения с вводом данных на ChromeOS и других устройствах Android с большими экранами, следует обратить внимание на следующие оптимизации:
- Добавьте и протестируйте базовую поддержку клавиатуры, например, навигацию с помощью клавиш со стрелками и клавиши Tab, клавишу Enter для подтверждения ввода текста и клавишу Space для воспроизведения/паузы в мультимедийных приложениях.
- Добавьте стандартные сочетания клавиш там, где это применимо, например
ctrl+zдля отмены действия,ctrl+sдля сохранения. - Протестируйте основные взаимодействия с мышью, такие как щелчок правой кнопкой мыши для вызова контекстного меню, изменение значка при наведении курсора и события прокрутки колесиком мыши/трекпадом для пользовательских элементов интерфейса.
- Протестируйте устройства ввода, специфичные для каждого приложения, такие как стилус для графических приложений, игровые контроллеры для игр и MIDI-контроллеры для музыкальных приложений.
- Рассмотрите возможность расширения поддержки ввода, которая могла бы выделить приложение в настольных средах: сенсорная панель в качестве кроссфейдера для диджейских приложений, захват мыши для игр и обширные сочетания клавиш для опытных пользователей.
Клавиатура
Способ, которым ваше приложение реагирует на ввод с клавиатуры, влияет на удобство работы на настольном компьютере. Существует три типа ввода с клавиатуры: навигация, нажатия клавиш и сочетания клавиш.
Навигация
В приложениях с сенсорным управлением навигация с помощью клавиатуры используется редко, но пользователи ожидают её наличия. Она также может быть необходима пользователям с особыми потребностями как на телефонах, так и на настольных компьютерах.
Для многих приложений достаточно навигации с помощью клавиш со стрелками и клавиши Tab, и она в основном обрабатывается автоматически фреймворком Android. Например, элемент Button по умолчанию находится в фокусе, и навигация с помощью клавиатуры, как правило, должна работать без дополнительного кода. Чтобы включить навигацию с помощью клавиатуры для элементов, которые по умолчанию не находятся в фокусе, разработчикам следует пометить их как фокусируемые. Это можно сделать программно или в XML-файле следующим образом. Дополнительную информацию см. в документации по обработке фокуса .
yourView.isFocusable = 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
Рекомендуется перед каждым релизом проверять доступ ко всем функциям приложения, используя только клавиатуру. Наиболее часто используемые действия должны быть доступны без мыши или сенсорного ввода.
Примечание: Помните, что поддержка клавиатуры может быть необходима пользователям с особыми потребностями.
Нажатия клавиш
Для ввода текста, который обрабатывается экранной виртуальной клавиатурой ( IME ), например, EditText , приложения должны вести себя должным образом в ChromeOS без дополнительной работы со стороны разработчика. Для нажатий клавиш, которые не могут быть предсказаны фреймворком, приложениям потребуется обрабатывать поведение самостоятельно. Это особенно актуально для приложений с пользовательскими представлениями.
В качестве примеров можно привести приложения для чата, использующие клавишу Enter для отправки сообщения, медиаприложения, запускающие/останавливающие воспроизведение с помощью клавиши Space, и игры, в которых управление движением осуществляется с помощью клавиш W, A, S и D.
Большинство приложений переопределяют событие onKeyUp и добавляют ожидаемое поведение для каждого полученного кода клавиши следующим образом.
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) } }
Использование события onKeyUp предотвращает получение приложениями нескольких событий, если клавиша удерживается или медленно отпускается. Игры и приложения, которые ожидают, что пользователи будут удерживать клавиши клавиатуры, могут отслеживать событие onKeyDown .
В зависимости от потребностей приложения, переопределение onKeyUp для всего Activity обычно обеспечивает необходимое поведение. При необходимости можно добавить onKeyListener к конкретному представлению. Например, приложение может отслеживать нажатие клавиши Enter только в определенном EditText, а не в Activity, чтобы реализовать функцию отправки только тогда, когда пользователь набирает текст в чате.
При добавлении поддержки клавиатуры следуйте документации по обработке клавиатуры Android.
Ярлыки
В настольных средах ожидаются стандартные сочетания клавиш ctrl , alt и shift . Если приложение их не использует, это может вызывать у пользователей чувство разочарования и некорректной работы. Опытные пользователи также ценят сочетания клавиш для часто используемых задач, специфичных для приложения. Сочетания клавиш упрощают использование приложения и отличают его от приложений, в которых их нет.
К числу распространенных сочетаний клавиш относятся сохранение ( ctrl + s ), отмена ( ctrl + z ) и повтор ( ctrl + shift + z ). Примеры более сложных сочетаний клавиш см. в списке сочетаний клавиш VLC Media Player .
Сочетания клавиш можно реализовать с помощью dispatchKeyShortcutEvent . Эта функция перехватывает все комбинации мета-клавиш ( alt , ctrl и shift ) для заданного кода клавиши. Для проверки наличия конкретной мета-клавиши используйте KeyEvent.isCtrlPressed() , KeyEvent.isShiftPressed() , KeyEvent.isAltPressed() или KeyEvent.hasModifiers() .
Разделение кода сочетаний клавиш от обработки других нажатий клавиш (таких как onKeyUp или onKeyDown ) может упростить сопровождение кода и сохранить автоматическое принятие мета-клавиш без необходимости вручную проверять их каждый раз. Разрешение всех комбинаций мета-клавиш также может быть удобнее для пользователей, привыкших к различным раскладкам клавиатуры и операционным системам.
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) } } }
Также можно реализовать сочетания клавиш в 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 } } else -> super.onKeyUp(keyCode, event) } }
Поддержка мыши и тачпада
ChromeOS автоматически обрабатывает большинство событий мыши и трекпада, чтобы они действовали как сенсорные события на телефоне Android. Это включает в себя прокрутку двумя пальцами по тачпаду/колесику мыши. Большинству приложений обычно достаточно обрабатывать только три события, характерные для настольных компьютеров: щелчок правой кнопкой мыши , наведение курсора и перетаскивание .
Щелчок правой кнопкой мыши
Любые действия, которые приводят к отображению контекстного меню в приложении, например, длительное нажатие на элемент списка, также должны реагировать на события щелчка правой кнопкой мыши. Для обработки событий щелчка правой кнопкой мыши приложениям следует зарегистрировать View.OnContextClickListener . Подробную информацию о создании контекстного меню см. в документации Android по контекстному меню .
yourView.setOnContextClickListener { view -> showContextMenu() true }
Примечание: любые элементы, зарегистрированные для контекстного меню с помощью Activity.registerForContextMenu() , должны автоматически работать как при длительном нажатии, так и при щелчке правой кнопкой мыши без необходимости регистрации обработчика события клика по контексту.
Ховер
Разработчики могут сделать макеты своих приложений более удобными и удобными в использовании, обрабатывая события наведения курсора. Это особенно актуально для пользовательских представлений. Два наиболее распространенных примера:
- Указывая пользователям на наличие у элемента интерактивного поведения, например, возможности клика или редактирования, путем изменения значка указателя мыши.
- Добавление визуальной обратной связи к элементам в большом списке или сетке при наведении на них указателя мыши.
// 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(applicationContext, PointerIcon.TYPE_HAND) false // listener did not consume the event. }
Перетаскивание
В многооконном режиме пользователи ожидают возможности перетаскивать элементы между приложениями. Это справедливо как для устройств ChromeOS, так и для планшетов, телефонов и складных устройств в режиме разделенного экрана.
Разработчикам следует учитывать вероятность того, что пользователи будут перетаскивать элементы в их приложение. К распространенным примерам относятся: фоторедакторы должны ожидать получения фотографий, аудиоплееры — аудиофайлов, а программы для рисования — фотографий.
Чтобы добавить поддержку перетаскивания, следуйте инструкциям в документации Android по функции перетаскивания и ознакомьтесь с этой статьей в блоге ChromeOS .
Особые соображения для ChromeOS
- Для работы с файлами из приложения «Файлы» в ChromeOS найдите MIME-тип
application/x-arc-uri-list - Не забудьте запросить разрешение с помощью
requestDragAndDropPermissionsдля доступа к элементам, перетащенным извне приложения. - Для перетаскивания элемента в другие приложения необходимо наличие флага
View.DRAG_FLAG_GLOBAL
Поддержка множественного выбора
Если ваше приложение содержит списки или сетки, подумайте, будет ли пользователям полезна поддержка множественного выбора. Качественный интерфейс множественного выбора с помощью мыши и трекпада часто включает в себя такие функции, как выделение полосами. Реализация этого самостоятельно может быть сложной задачей, но вы можете использовать библиотеку RecyclerView Selection .

Расширенная поддержка указателей
Приложениям, которые выполняют расширенную обработку ввода с мыши и тачпада, следует следовать документации Android для View.onGenericMotionEvent() и использовать MotionEvent.getSource() для различения SOURCE_MOUSE и SOURCE_TOUCHSCREEN .
Изучите MotionEvent , чтобы реализовать необходимое поведение:
- Движение генерирует события
ACTION_HOVER_MOVE - Кнопки генерируют события
ACTION_BUTTON_PRESSиACTION_BUTTON_RELEASE. Вы также можете проверить текущее состояние всех кнопок мыши/трекпада с помощьюgetButtonState(). - Прокрутка колесиком мыши генерирует события
ACTION_SCROLL
Стилус
Многие Chromebook поставляются со стилусом, и приложения для Android обрабатывают его как сенсорный ввод. Некоторые устройства также могут иметь графический планшет с USB или Bluetooth, например, Wacom Intuos . Приложения для Android могут принимать ввод через Bluetooth, но не будут работать с USB-входом.
Событие, связанное со стилусом, регистрируется как событие сенсорного экрана с помощью View.onTouchEvent() или View.onGenericMotionEvent() и содержит MotionEvent.getSource() типа SOURCE_STYLUS . MotionEvent также будет содержать дополнительные данные:
-
MotionEvent.getToolType()вернет значенияTOOL_TYPE_FINGER,TOOL_TYPE_STYLUSилиTOOL_TYPE_ERASERв зависимости от инструмента, соприкоснувшегося с поверхностью. -
MotionEvent.getPressure()будет сообщать о физическом давлении, приложенном к стилусу, если он поддерживается. -
MotionEvent.getAxisValue()сMotionEvent.AXIS_TILTиMotionEvent.AXIS_ORIENTATIONпозволяет считывать физический наклон и ориентацию стилуса, если это поддерживается.
Исторические моменты
Android обрабатывает входные события пакетами и передает их один раз за кадр. Стилус может сообщать о событиях с гораздо большей частотой, чем дисплей. При создании приложений для рисования важно проверять наличие событий, которые могли произойти в недавнем прошлом, используя API getHistorical :
-
MotionEvent.getHistoricalX() -
MotionEvent.getHistoricalY() -
MotionEvent.getHistoricalPressure() -
MotionEvent.getHistoricalAxisValue()
Отторжение ладони
ChromeOS пытается распознать, когда ладонь пользователя лежит на сенсорном экране. Однако это не всегда возможно. Иногда событие касания может быть передано приложению до того, как ОС распознает его как касание ладони. В этом случае касания будут отменены путем отправки события ACTION_CANCEL .
Это событие сообщает приложению, что определенные касания недействительны, и оно должно отменить все взаимодействия, вызванные этими касаниями. Например, приложение для рисования может временно рисовать новые линии сразу после их получения, чтобы обеспечить минимальную задержку, но окончательно зафиксировать их на холсте только после того, как серия касаний будет завершена без проблем. Если события касания отменяются в это время, временные линии могут быть стерты.
Примечание: Один из способов уменьшить количество лишних событий, связанных с движением ладони и пальцев, в приложениях для рисования и ввода текста — это добавить в пользовательский интерфейс настройку, которая отключает рисование с помощью сенсорного экрана и использует события стилуса только в этом режиме.
Приложения для ведения заметок
В ChromeOS есть специальный интент, который отображает зарегистрированные приложения для создания заметок пользователям. Чтобы зарегистрировать приложение в качестве приложения для заметок, добавьте следующее в манифест Android:
<intent-filter> <action android:name="org.chromium.arc.intent.action.CREATE_NOTE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
После регистрации приложения пользователь может выбрать его в качестве приложения для создания заметок по умолчанию. При запросе новой заметки приложение должно создать пустую заметку, готовую для ввода с помощью стилуса. Когда пользователь хочет добавить аннотацию к изображению (например, к скриншоту или загруженному изображению), приложение запускается с ClipData содержащим один или несколько элементов с URI content:// . Приложение должно создать заметку, используя первое прикрепленное изображение в качестве фонового изображения, и перейти в режим, в котором пользователь может рисовать на ней с помощью стилуса.
Тестирование способов создания заметок без использования стилуса.
Чтобы проверить, корректно ли приложение реагирует на команды создания заметок без активного стилуса, используйте следующий способ отображения параметров создания заметок:
- Переключитесь в режим разработчика и сделайте устройство доступным для записи.
- Нажмите
ctrl+alt+f2, чтобы открыть терминал. - Выполните команду
sudo vi /etc/chrome_dev.conf - Нажмите клавишу
iдля редактирования и добавьте--ash-enable-paletteна новую строку в конец файла. - Сохраните файл, нажав клавишу
Esc, затем набрав:,w,qи нажавEnter - Нажмите
ctrl+alt+f1, чтобы вернуться к стандартному интерфейсу ChromeOS.
Теперь на панели инструментов должно появиться меню для стилуса:
- Нажмите кнопку стилуса на панели инструментов и выберите «Новая заметка» . Откроется пустая заметка для рисования.
- Сделайте снимок экрана. На панели инструментов выберите кнопку стилуса > Сделать снимок экрана или загрузите изображение. В уведомлении должна появиться опция «Аннотировать изображение». Это запустит приложение с изображением, готовым к аннотированию.
Игровые контроллеры
Chromebook поддерживают до четырех игровых контроллеров. Разработчикам следует использовать стандартные API Android Game Controller для работы с ними.
Кнопки назначаются на общие значения в соответствии с общепринятой системой сопоставления . К сожалению, не все производители игровых контроллеров придерживаются одних и тех же правил сопоставления. Вы можете значительно улучшить пользовательский опыт, если позволите пользователям выбирать различные популярные варианты сопоставления кнопок контроллера.
Режим ввода перевода
ChromeOS по умолчанию включает режим преобразования ввода. Для большинства приложений Android этот режим помогает приложениям работать должным образом в среде рабочего стола. Например, он включает автоматическое включение прокрутки двумя пальцами на тачпаде, прокрутку колесиком мыши и сопоставление исходных координат дисплея с координатами окна. Как правило, разработчикам приложений не нужно самостоятельно реализовывать ни одно из этих действий.
Если приложение реализует пользовательское поведение ввода, например, определяет пользовательское действие масштабирования двумя пальцами на сенсорной панели, или эти преобразования ввода не обеспечивают ожидаемые приложением события ввода, вы можете отключить режим преобразования ввода, добавив следующий тег в манифест Android:
<uses-feature android:name="android.hardware.type.pc" android:required="false" />