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

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

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

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

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

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

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

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

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

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

Вы можете использовать Autofill в своем приложении, чтобы упростить извлечение сохраненных данных для пользователей. Autofill поддерживает текстовые компоненты через 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 , пользователи могут видеть кнопку на клавиатуре для Suggest strong password . Когда они нажимают на нее, появляется нижний лист, который позволяет им сохранить свои учетные данные. Вам не нужно реализовывать что-либо еще, чтобы пользователи имели этот опыт.

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

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

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

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

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

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

Чтобы настроить этот цвет подсветки, используйте CompositionLocal и укажите любой желаемый цвет. Цвет подсветки Autofill по умолчанию определен как 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 }
    )
}