Автозаполнение в Compose

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

Заполнение учётных данных и форм — трудоёмкая и подверженная ошибкам задача. Автозаполнение позволяет пользователям экономить время на заполнение полей и сводит к минимуму количество ошибок при вводе данных.

Всего несколько строк кода позволят вам реализовать функцию автозаполнения в Compose. Эта функция обеспечивает следующие преимущества для пользователей:

Заполнить учетные данные

Функция автозаполнения позволяет пользователям заполнять свои учетные данные следующими способами:

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

Сохранить учетные данные

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

  • Система открывает диалоговое окно сохранения, предлагающее пользователю сохранить информацию при вводе новой или обновлённой информации в поле с функцией автозаполнения. Сохранение можно выполнить двумя способами:
    • Явным образом, путем передачи информации (например, посредством нажатия кнопки)
    • Неявно, когда пользователь уходит со страницы
  • В зависимости от вашего поставщика учетных данных система может предложить пользователю надежный пароль, если в поле установлено значение ContentType.NewPassword .

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

Настроить автозаполнение

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

Страница настроек, на которой показано, как указать поставщика учетных данных.
Рисунок 1. Страница настроек, показывающая, как указать поставщика учетных данных.

Добавьте автозаполнение в текстовое поле, используя тип контента

Чтобы указать, что TextField поддерживает автозаполнение, задайте семантику ContentType с типами данных, которые может принимать поле. Это указывает службам автозаполнения, какие типы пользовательских данных могут быть релевантны этому полю. Используйте ContentType.Username , чтобы задать TextField , которое пользователи смогут заполнять своим именем.

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

Текстовое поле на основе значения

TextField(
    value = textFieldValue.value,
    onValueChange = {textFieldValue.value = it},
    modifier = Modifier.semantics { contentType = ContentType.Username }
)

Текстовое поле, зависящее от штата

TextField(
    state = rememberTextFieldState(),
    modifier = Modifier.semantics { contentType = ContentType.Username }
)

Добавить поля автозаполнения с несколькими типами

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

Все типы данных, доступные для сохранения с помощью функции автозаполнения, см. в справочнике ContentType .

Текстовое поле на основе значения

TextField(
    value = textFieldValue.value,
    onValueChange = { textFieldValue.value = it },
    modifier = Modifier.semantics {
        contentType = ContentType.Username + ContentType.EmailAddress
    }
)

Текстовое поле, зависящее от штата

TextField(
    state = rememberTextFieldState(),
    modifier = Modifier.semantics {
        contentType = ContentType.Username + ContentType.EmailAddress
    }
)

Заполнить данные с помощью автозаполнения

При добавлении ContentType в TextField вам не нужно будет делать ничего другого, чтобы пользователи могли заполнять учетные данные.

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

Чипы на текстовой панели инструментов, отображающие сохраненные учетные данные.
Рисунок 2. Фишки на текстовой панели инструментов, отображающие сохраненные учетные данные.

Сохраняйте данные с помощью автозаполнения через навигацию

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

Сохраняйте данные явно с помощью функции автозаполнения

Чтобы явно сохранить новые учётные данные через текстовые поля с функцией автозаполнения, контекст автозаполнения должен быть зафиксирован (или отменён) менеджером автозаполнения. Затем локальный менеджер автозаполнения при необходимости взаимодействует с фреймворком автозаполнения. Если вы хотите удалить введённые пользователем учётные данные, вызовите метод AutofillManager.cancel , чтобы удалить все ожидающие данные без их сохранения.

В следующих фрагментах показано, как сохранять данные с помощью функции автозаполнения явно с помощью кнопки:

  1. Создайте локальную переменную для хранения менеджера автозаполнения, которую можно получить следующим образом:

    val autofillManager = LocalAutofillManager.current

  2. В TextField(s) добавьте выбранный тип контента с помощью Modifier.semantics :

    • С текстовыми полями на основе значений:

      val autofillManager = LocalAutofillManager.current
      
      Column {
          TextField(
              value = textFieldValue.value,
              onValueChange = { textFieldValue.value = it },
              modifier = Modifier.semantics { contentType = ContentType.NewUsername }
          )
      
          Spacer(modifier = Modifier.height(16.dp))
      
          TextField(
              value = textFieldValue.value,
              onValueChange = { textFieldValue.value = it },
              modifier = Modifier.semantics { contentType = ContentType.NewPassword }
          )
      }

    • С текстовыми полями, зависящими от состояния:

      val autofillManager = LocalAutofillManager.current
      
      Column {
          TextField(
              state = rememberTextFieldState(),
              modifier = Modifier.semantics { contentType = ContentType.NewUsername }
          )
      
          Spacer(modifier = Modifier.height(16.dp))
      
          TextField(
              state = rememberTextFieldState(),
              modifier = Modifier.semantics { contentType = ContentType.NewPassword }
          )
      }

  3. При необходимости зафиксируйте контекст автозаполнения нажатием кнопки:

    • С текстовыми полями на основе значений:

      val autofillManager = LocalAutofillManager.current
      
      Column {
          TextField(
              value = textFieldValue.value,
              onValueChange = { textFieldValue.value = it },
              modifier = Modifier.semantics { contentType = ContentType.NewUsername },
          )
      
          Spacer(modifier = Modifier.height(16.dp))
      
          TextField(
              value = textFieldValue.value,
              onValueChange = { textFieldValue.value = it },
              modifier = Modifier.semantics { contentType = ContentType.NewPassword },
          )
      
          // Submit button
          Button(onClick = { autofillManager?.commit() }) { Text("Reset credentials") }
      }

    • С текстовыми полями, зависящими от состояния:

      val autofillManager = LocalAutofillManager.current
      
      Column {
          TextField(
              state = rememberTextFieldState(),
              modifier = Modifier.semantics { contentType = ContentType.NewUsername },
          )
      
          Spacer(modifier = Modifier.height(16.dp))
      
          TextField(
              state = rememberTextFieldState(),
              modifier = Modifier.semantics { contentType = ContentType.NewPassword },
          )
      
          // Submit button
          Button(onClick = { autofillManager?.commit() }) { Text("Reset credentials") }
      }

Commit вызывается каждый раз, когда пользователь покидает экран. Если кнопка «Отправить» связана с навигацией, то вызывать Commit не нужно. Если вы всё равно хотите, чтобы нажатие кнопки «Отправить» вызывало диалоговое окно сохранения, добавьте Commit здесь.

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

Нижний лист предлагает пользователям сохранить пароль.
Рисунок 3. Нижний лист, предлагающий пользователям сохранить пароль.

Сохраните данные с помощью автозаполнения, предлагая надежный пароль

В зависимости от вашего поставщика учётных данных, при использовании типов контента NewUsername и NewPassword пользователи могут видеть на клавиатуре кнопку « Предложить надёжный пароль» . При нажатии на неё открывается нижняя панель, позволяющая сохранить учётные данные. Вам не нужно настраивать что-либо ещё, чтобы пользователи получили эту возможность.

Чип, предлагающий надежный пароль, на панели инструментов клавиатуры.
Рисунок 4. Чип предложения надежного пароля на панели инструментов клавиатуры.
Нижний лист предлагает пользователям использовать надежный пароль.
Рисунок 5. Нижний лист с предложением пользователям использовать надежный пароль.

Поиск неисправностей

Если при запуске процесса сохранения пользовательского пути нажать кнопку «Не сейчас» несколько раз, ваш поставщик учётных данных может перестать отображать нижнюю панель. Чтобы снова включить её и вернуть, необходимо удалить определённые приложения, блокирующие функцию «Запомнить этот пароль?».

Нижний лист предлагает пользователям сохранить пароль.
Рисунок 6. Нижний лист, предлагающий пользователям сохранить пароль.

Дальнейшая настройка автозаполнения

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

Чтобы настроить цвет подсветки, используйте CompositionLocal и укажите нужный вам цвет. Цвет подсветки автозаполнения по умолчанию определён как Color(0x4dffeb3b) .

Текстовые поля на основе значений

val customHighlightColor = Color.Red

CompositionLocalProvider(LocalAutofillHighlightColor provides customHighlightColor) {
    TextField(
        value = textFieldValue.value,
        onValueChange = { textFieldValue.value = it },
        modifier = Modifier.semantics { contentType = ContentType.Username }
    )
}

Текстовые поля, зависящие от состояния

val customHighlightColor = Color.Red

CompositionLocalProvider(LocalAutofillHighlightColor provides customHighlightColor) {
    TextField(
        state = rememberTextFieldState(),
        modifier = Modifier.semantics { contentType = ContentType.Username }
    )
}