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

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

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

Клавиатура

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

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

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

Котлин

yourView.isFocusable = true

Ява

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

Ява

// 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() и добавляют ожидаемое поведение для каждого полученного кода ключа:

Котлин

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)
    }
}

Ява

@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)
    }
  }
}

Ява

@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)
  }
}

Ява

@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.

Андроид 12

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

Андроид 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:// . Приложение должно создать заметку, которая использует первое прикрепленное изображение в качестве фонового изображения, и войти в режим, в котором пользователь может рисовать на экране стилусом.

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

[TBD удалить раздел.]

Чтобы проверить, правильно ли приложение реагирует на намерения создания заметок без активного стилуса, используйте следующий метод для отображения параметров создания заметок в 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
}

Ява

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.
}

Ява

// 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" />

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