Autocompletar en Compose

Algunas apps, como los administradores de contraseñas, pueden completar los componentes en otras con datos que proporcionó el usuario. Esas apps que completan datos de otras 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. Autocompletar permite a los usuarios ahorrar tiempo dedicado a 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 proporciona los siguientes beneficios a los usuarios:

Completar credenciales

Autocompletar permite a los usuarios completar sus credenciales de las siguientes maneras:

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

Guardar credenciales

Los usuarios pueden guardar credenciales a través de Autocompletar de las siguientes maneras:

  • El sistema activa un diálogo de guardado, que le solicita al usuario que guarde la información cuando ingresa información nueva o actualizada en un campo habilitado para Autocompletar. El guardado se puede realizar de dos maneras:
    • De forma explícita, confirmando la 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 sugerir una contraseña segura al usuario 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 Autocompletar en tu dispositivo o emulador, debes activar Autocompletar 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.

Agrega Autocompletar a tu campo de texto con el tipo de contenido

Para indicar que un TextField está habilitado para Autocompletar, establece la semántica de 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 estableces la semántica de 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, sus credenciales se le entregan a través de Autocompletar.

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 estados

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 adopte 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 ver todos los tipos de datos disponibles para 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 estados

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

Completa 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, ve un chip en la barra de herramientas sobre el teclado que le solicita 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.

Guarda 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 Autocompletar, guardará automáticamente la información de las credenciales cuando un usuario abandone la página sin requerir ningún código adicional.

Guarda 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 Autocompletar local se comunica con Autofill Framework cuando es necesario. Si deseas 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 con un botón:

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

    val autofillManager = LocalAutofillManager.current

  2. En tus TextField(s), agrega el tipo de contenido elegido 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 estados:

      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 a través de un clic en un botón:

    • Con campos de texto basados en valores:

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

    • Con campos de texto basados en estados:

      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 abandona la pantalla. Si un botón Submit está vinculado a la navegación, no es necesario llamar a Commit. Si aún quieres que hacer clic en Submit active el diálogo de guardado, 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

Guarda datos con Autocompletar a través de la sugerencia de contraseña segura

Según tu proveedor de credenciales, cuando usas 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 él, 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 habilitarla y que aparezca una vez más, debes quitar las apps específicas que bloquearon la opción "¿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

Personaliza aún más Autocompletar

En un recorrido típico del usuario de Autocompletar, cuando un componente habilitado para Autocompletar se completa 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 estados

val customHighlightColor = Color.Red

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