Autocompletar en Compose

Algunas apps, como los administradores de contraseñas, pueden completar los componentes en otras apps con datos que proporcionó el usuario. Las apps que completan los componentes de otras apps se denominan servicios de autocompletado. Autofill Framework administra la comunicación entre una app y un servicio de autocompletado.

Completar credenciales y formularios es una tarea lenta y propensa a errores. El autocompletado permite que los usuarios ahorren tiempo al completar campos y minimiza los errores de entrada del usuario.

Con solo unas pocas líneas de código, puedes implementar Autocompletar en Compose. Esta función ofrece los siguientes beneficios a los usuarios:

Cómo completar las credenciales

La función de Autocompletar permite a los usuarios propagar sus credenciales de las siguientes maneras:

  • El sistema muestra sugerencias de autocompletado al usuario cuando presiona un campo en el que se establece la semántica de autocompletado.
  • El sistema muestra sugerencias de Autocompletar para el usuario y las filtra según lo que escribe.

Guarda credenciales

Los usuarios pueden guardar credenciales con la función de autocompletado de las siguientes maneras:

  • El sistema activa un diálogo de guardar, que le solicita al usuario que guarde la información cuando ingresa información nueva o actualizada en un campo habilitado para Autocompletar. Puedes guardar los cambios de dos maneras:
    • De forma explícita, cuando se confirma información (por ejemplo, a través de un clic en un botón)
    • De forma implícita, cuando un usuario abandona la página
  • Según tu proveedor de credenciales, el sistema puede sugerirle al usuario una contraseña segura cuando un campo tiene establecido ContentType.NewPassword.

Puedes usar Autocompletar en tu app para optimizar la recuperación de datos guardados para los usuarios. Autocompletar admite componentes de texto a través de BasicTextField y todos los campos de texto de Material que se basan en ese componente.

Conf. Autocompl.

Antes de usar las APIs de Autofill en tu dispositivo o emulador, debes activar Autofill en Configuración. Allí, puedes especificar un proveedor de credenciales para que Autocompletar almacene tus credenciales.

Una página de configuración que muestra cómo especificar un proveedor de credenciales.
Figura 1: Una página de configuración que muestra cómo especificar un proveedor de credenciales.

Cómo agregar Autocompletar a tu campo de texto con el tipo de contenido

Para indicar que un TextField está habilitado para Autocompletar, establece la semántica ContentType con los tipos que el campo puede aceptar. Esto indica a los servicios de autocompletar qué tipo de datos del usuario podrían ser relevantes para este campo específico. Usa ContentType.Username para establecer un TextField que los usuarios puedan completar con su nombre de usuario.

Si configuras la semántica ContentType, tus usuarios podrán acceder a la información de Autocompletar que ya se guardó en el proveedor de credenciales de su dispositivo. Por ejemplo, si un usuario ya accedió a tu app a través del navegador Chrome en su laptop y guardó su contraseña a través de un proveedor de credenciales, Autocompletar le proporcionará sus credenciales.

Campo de texto basado en valores

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

Campo de texto basado en el estado

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

Agrega campos de Autocompletar con varios tipos

En algunos casos, es posible que desees que tu TextField asuma más de un ContentType. Por ejemplo, un campo de acceso puede aceptar una dirección de correo electrónico o un nombre de usuario. Puedes agregar varios tipos de contenido a tu TextField con el operador +.

Para conocer todos los tipos de datos que se pueden guardar con Autocompletar, consulta la ContentType referencia.

Campo de texto basado en valores

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

Campo de texto basado en el estado

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

Cómo completar datos con Autocompletar

Cuando agregues un ContentType en un TextField, no necesitarás hacer nada más para que los usuarios puedan completar las credenciales.

Cuando un usuario hace clic en un campo habilitado para Autocompletar, si hay datos relevantes almacenados, verá un chip en la barra de herramientas sobre el teclado que le indicará que complete las credenciales.

Chips en la barra de herramientas de texto que muestran las credenciales guardadas.
Figura 2: Chips en la barra de herramientas de texto que muestran las credenciales guardadas.

Cómo guardar datos con Autocompletar a través de la navegación

Compose intenta determinar automáticamente cuándo un usuario navega desde una página y confirma las credenciales ingresadas. Una vez que un campo está habilitado para la función Autocompletar, guardará automáticamente la información de las credenciales cuando un usuario abandone la página sin necesidad de código adicional.

Cómo guardar datos de forma explícita con Autocompletar

Para guardar explícitamente credenciales nuevas a través de campos de texto con Autocompletar, el administrador de Autocompletar debe confirmar (o cancelar) el contexto de Autocompletar. Luego, el administrador de Autofill local se comunica con Autofill Framework cuando es necesario. Si quieres quitar las credenciales que ingresó el usuario, llama a AutofillManager.cancel para borrar los datos pendientes sin guardarlos.

Los siguientes fragmentos muestran cómo guardar datos con Autocompletar de forma explícita usando un botón:

  1. Crea una variable local para contener el administrador de Autofill, que se puede recuperar de la siguiente manera:

    val autofillManager = LocalAutofillManager.current

  2. En tu TextField(s), agrega el tipo de contenido que elegiste a través de Modifier.semantics:

    • Con campos de texto basados en valores:

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

    • Con campos de texto basados en el estado:

      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. Confirma el contexto de Autocompletar según sea necesario haciendo clic en un botón:

    • Con campos de texto basados en valores:

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

    • Con campos de texto basados en el estado:

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

Se llama a Commit cada vez que un usuario sale de la pantalla. Si un botón Enviar está vinculado a la navegación, no es necesario llamar a Commit. Si aún quieres que al hacer clic en Enviar se active el diálogo de guardar, agrega Commit aquí.

Cuando el usuario haga clic en el botón, verá esta hoja inferior que le solicitará que guarde las credenciales en el proveedor de credenciales seleccionado:

Hoja inferior que solicita a los usuarios que guarden la contraseña.
Figura 3: Hoja inferior que solicita a los usuarios que guarden la contraseña.

Cómo guardar datos con Autocompletar a través de la sugerencia de contraseñas seguras

Según tu proveedor de credenciales, cuando uses los tipos de contenido NewUsername y NewPassword, es posible que los usuarios vean un botón en el teclado para Sugerir contraseña segura. Cuando hacen clic en esta opción, aparece una hoja inferior que les permite guardar sus credenciales. No necesitas implementar nada más para que los usuarios tengan esta experiencia.

El chip para sugerir contraseñas seguras en la barra de herramientas del teclado
Figura 4: El chip de sugerencia de contraseña segura en la barra de herramientas del teclado.
Hoja inferior que solicita a los usuarios que usen una contraseña segura.
Figura 5: Hoja inferior que solicita a los usuarios que usen una contraseña segura.

Solución de problemas

Cuando invocas el recorrido del usuario de "guardado", si haces clic en "Ahora no" más de una vez, es posible que tu proveedor de credenciales ya no muestre la hoja inferior. Para volver a habilitarlo y que aparezca una vez más, debes quitar las apps específicas que bloquearon el mensaje "¿Quieres recordar esta contraseña?".

Hoja inferior que solicita a los usuarios que guarden la contraseña.
Figura 6: Hoja inferior que solicita a los usuarios que guarden la contraseña.

Cómo personalizar aún más Autocompletar

En un recorrido del usuario típico de Autocompletar, cuando un componente habilitado para Autocompletar se completó con credenciales, cambia de color y se destaca para indicarle al usuario que Autocompletar se completó correctamente.

Para personalizar este color de resaltado, usa CompositionLocal y proporciona el color que desees. El color de resaltado predeterminado de Autocompletar se define como Color(0x4dffeb3b).

Campos de texto basados en valores

val customHighlightColor = Color.Red

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

Campos de texto basados en el estado

val customHighlightColor = Color.Red

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