Alternar campo de contraseña jetpack componer

3 minutos de lectura

avatar de usuario de clouddy
nublado

Hola, estoy tratando de cambiar visualTransformation dinámicamente cuando el usuario hace clic en el botón para ver la contraseña. Puedo filtrar la contraseña, pero no pude mostrarla en texto sin formato. ¿Alguna idea para eso? Esto es lo que tengo hasta ahora.

fun UserInputText(
    keyboardType: KeyboardType = KeyboardType.Text,
    onTextChanged: (TextFieldValue) -> Unit,
    textFieldValue: TextFieldValue,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    borderColor: Color = editTextBorderColor,
    keyboardShown: Boolean,
    onTextFieldFocused: (Boolean) -> Unit,
    focusState: Boolean,
    placeholder: String = "",
    modifier: Modifier = Modifier
) {
    Box(
        modifier = modifier.border(
            width = 2.dp,
            color = borderColor,
            shape = RoundedCornerShape(16.dp)
        )
    ) {
        var lastFocusState by remember { mutableStateOf(FocusState.Inactive) }
        val focusRequester = FocusRequester()
        val focusRequesterModifier = Modifier.focusRequester(focusRequester)

        BasicTextField(
            value = textFieldValue,
            onValueChange = { onTextChanged(it) },
            modifier =
            modifier.focus().then(focusRequesterModifier)
                .align(Alignment.TopStart)
                .focusObserver { state ->
                    if (lastFocusState != state) {
                        onTextFieldFocused(state == FocusState.Active)
                    }
                    lastFocusState = state
                },
            keyboardOptions = KeyboardOptions(
                keyboardType = keyboardType,
                imeAction = ImeAction.Send
            ),
            visualTransformation = visualTransformation,
            maxLines = 1,
            cursorColor = inputTextColor,
            textStyle = MaterialTheme.typography.body1.copy(color = inputTextColor)
        )
        if(keyboardType == KeyboardType.Password) {
            Image(
                vectorResource(id = R.drawable.ic_icons_watch_count_24), modifier = Modifier
                    .align(Alignment.TopEnd)
                    .padding(end = 16.dp, top = 16.dp).clickable(onClick = {})
            )
        }
    }
}

Avatar de usuario de Gabriele Mariotti
gabriele mariotti

Puedes usar el estándar TextField componible:

var password by rememberSaveable { mutableStateOf("") }
var passwordVisible by rememberSaveable { mutableStateOf(false) }

TextField(
    value = password,
    onValueChange = { password = it },
    label = { Text("Password") },
    singleLine = true,
    placeholder = { Text("Password") },
    visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
    trailingIcon = {
        val image = if (passwordVisible)
            Icons.Filled.Visibility
        else Icons.Filled.VisibilityOff

        // Please provide localized description for accessibility services
        val description = if (passwordVisible) "Hide password" else "Show password"

        IconButton(onClick = {passwordVisible = !passwordVisible}){
            Icon(imageVector  = image, description)
        }
    }
)

ingrese la descripción de la imagen aquí

Nota: para usar Icons.Filled.Visibility y Icons.Filled.VisibilityOff agregar en las dependencias: implementation "androidx.compose.material:material-icons-extended:$compose_version"

  • Buena solución. ¡Impresionante!

    – Gary Chen

    25 de agosto de 2021 a las 12:24

  • Usar cadenas vacías para las descripciones de contenido es un mal hábito, es mejor configurarlo como nulo para indicar que es puramente decorativo o proporcionar una cadena real en su ejemplo para que las personas entiendan por qué está ahí. No estoy seguro de cómo funcionaría un lector de pantalla con Compose TextField usando PasswordVisualTransform, pero no contaría con que este contentDescription sea innecesario.

    – llave inglesa

    21 de diciembre de 2021 a las 10:44

  • @omiwrench Es solo un ejemplo. En cualquier caso, dado que la respuesta muestra cómo implementar un campo de contraseña, es correcto el enfoque para administrar también la descripción. Respuesta actualizada. Gracias por la respuesta.

    – Gabriele Mariotti

    8 de marzo de 2022 a las 11:22

Mira esto:

    var passwordVisibility: Boolean by remember { mutableStateOf(false) }
    TextField(value = "Enter Password",
        visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(),
        leadingIcon = {
            IconButton(onClick = {
                passwordVisibility = !passwordVisibility
            }) {
                Icon(imageVector = vectorResource(id = R.drawable.ic_icons_watch_count_24))
            }
        },
        onValueChange = { })
    

Ocultar/Mostrar contraseña en jetpack componer

 @Composable
    fun CommonTextFieldPassword(
        text: MutableState<String>,
        placeholder: String,
        trailingIcon: Int = R.drawable.eye,
        visibility: MutableState<Boolean> = remember { mutableStateOf(false) }
    ) {
        TextField(
            value = text.value,
            onValueChange = { text.value = it },
            colors = TextFieldDefaults.textFieldColors(
                backgroundColor = Color.White,
                focusedLabelColor = fadedTextColor,
                textColor = headingColor,
                unfocusedLabelColor = fadedTextColor,
                unfocusedIndicatorColor = fadedTextColor,
                focusedIndicatorColor = headingColor
            ),
            label = { Text(text = placeholder) },
            trailingIcon = {
                Icon(
                    painter = painterResource(id = trailingIcon),
                    contentDescription = "",
                    modifier = Modifier
                        .size(25.dp)
                        .clickable {
                            visibility.value = !visibility.value
                        },
                    tint = if (visibility.value) titleColor else fadedTextColor
                )
            },
            modifier = Modifier.fillMaxWidth(),
            visualTransformation = if (visibility.value) VisualTransformation.None else PasswordVisualTransformation()
        )
    }

¿Ha sido útil esta solución?