Управление съемной клавиатурой

Значок с тремя звездами

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

Во всех случаях данные, связанные с клавиатурой, хранятся в объекте Configuration. Поля keyboard и keyboardHidden объекта конфигурации содержат информацию о типе клавиатуры и ее доступности.

Рекомендации

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

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

  1. Позвольте системе воссоздать запущенное действие, а вы позаботьтесь об управлении состоянием приложения.
  2. Самостоятельно управлять изменением конфигурации (активность не будет воссоздана):
    • Объявить все значения конфигурации, связанные с клавиатурой
    • Как создать обработчик изменений конфигурации

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

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

В Jetpack Compose можно реагировать на изменения конфигурации клавиатуры двумя способами:

  1. Реактивный интерфейс. Считывайте текущее состояние конфигурации непосредственно в компонентах Composables с помощью LocalConfiguration.current. Когда клавиатура подключается или отключается, интерфейс автоматически перестраивается, чтобы адаптироваться к новому состоянию.
  2. Обратный вызов побочного эффекта. Используйте DisposableEffect с учетом жизненного цикла, чтобы зарегистрировать прослушиватель изменений конфигурации в основном объекте Activity. Это позволит вам запускать события, не связанные с интерфейсом (например, ведение журнала или аналитику), без воссоздания объекта Activity или создания фиктивных элементов представления.

Ингредиенты

  • android:configChanges – атрибут элемента <activity> манифеста приложения. Сообщает системе об изменениях конфигурации, которыми управляет приложение.
  • LocalConfiguration: локальный поставщик, который предоставляет информацию о текущем устройстве Configuration.
  • DisposableEffect: API побочных эффектов Compose, который выполняет блок кода, когда composable-функция входит в композицию, и очищает его, когда она выходит из нее.

Шаги

Объявите атрибут configChanges и добавьте связанные с клавиатурой значения, чтобы предотвратить воссоздание действий. Затем используйте LocalConfiguration.current, чтобы динамически адаптировать макет Composable, или зарегистрируйте прослушиватель конфигурации с помощью DisposableEffect.

1. Атрибут declare configChanges

Обновите элемент <activity> в манифесте приложения, добавив значения keyboard|keyboardHidden в список уже управляемых изменений конфигурации:

<activity
      …
      android:configChanges="...|keyboard|keyboardHidden">

2. Как реагировать на изменения конфигурации клавиатуры

Чтобы обрабатывать изменения конфигурации в Jetpack Compose, используйте один из следующих вариантов в зависимости от того, обновляете ли вы интерфейс или выполняете побочный эффект:

  • Вариант А. Адаптивный интерфейс (рекомендуется)

    Считывайте тип клавиатуры непосредственно из LocalConfiguration.current. Когда аппаратная клавиатура подключается или отключается, это значение меняется, и Compose автоматически перекомпоновывает интерфейс.

    val configuration = LocalConfiguration.current
    val isPhysicalKeyboardAttached = configuration.keyboard == Configuration.KEYBOARD_QWERTY
    
    if (isPhysicalKeyboardAttached) {
        // Render layout optimized for physical keyboard
    } else {
        // Render default layout
    }

  • Вариант Б. Слушатель побочных эффектов

    Если при изменении конфигурации вам нужно выполнить побочный эффект (например, зарегистрировать событие, обновить локальную базу данных или запустить аналитику), используйте DisposableEffect, чтобы зарегистрировать прослушиватель изменений конфигурации на хосте ComponentActivity.

    val context = LocalActivity.current
    DisposableEffect(context) {
        val activity = context as? ComponentActivity
        val listener = Consumer<Configuration> { newConfig ->
            val hasKeyboard = newConfig.keyboard == Configuration.KEYBOARD_QWERTY
            // Trigger non-UI actions, analytics, etc.
        }
        activity?.addOnConfigurationChangedListener(listener)
        onDispose {
            activity?.removeOnConfigurationChangedListener(listener)
        }
    }

Результаты

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

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

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