Josef M
Josef M

Reputation: 396

Using Toggle in a password field in jetpack compose

I am trying to use toggle in a password field. This is my code so far but for some reason it wont work. How can I achieve toggling a password as in this image? Much appreciated!

Image: https://gyazo.com/5ad35b44dc955e0846c68f61ec9630b0

    Column(
        modifier = Modifier.padding(20.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally

    ) {

        val username = remember { mutableStateOf(TextFieldValue()) }
        val password = remember { mutableStateOf("") }
        var revealPassword: MutableState<Boolean> =
            remember { mutableStateOf(false) } // To reveal the password with toggle


        Text(text = "Sign in", style = TextStyle(fontSize = 40.sp, fontFamily = FontFamily.Cursive))
        Text(
            text = "here",
            style = TextStyle(fontSize = 40.sp, fontFamily = FontFamily.Cursive)
        )
        // PASSWORD
        Spacer(modifier = Modifier.height(20.dp))
        OutlinedTextField(
            value = password.value,
            onValueChange = { newText ->
                password.value = newText
            },

            visualTransformation = if (revealPassword.value) {
                VisualTransformation.None
            } else {
                PasswordVisualTransformation()
            },
            trailingIcon = {
                if (revealPassword.value) {
                    IconButton(onClick = {
         (I changed this!! -->) revealPassword.Value = false
                    }) { Icon(imageVector = Icons.Filled.Visibility, contentDescription = null) }
                } else {
                  IconButton(onClick = { 
(I changed this!! -->) revealPassword.Value = true }) {
                        Icon(imageVector = Icons.Filled.VisibilityOff, contentDescription = null)
                    }
                }
            },

            label = { Text(text = "Password") },
            singleLine = true,
            leadingIcon = { Icon(imageVector = Icons.Default.Lock, contentDescription = null) },
            modifier = Modifier
                .fillMaxWidth(180F),
            
            )

Upvotes: 1

Views: 1684

Answers (2)

talhatek
talhatek

Reputation: 355

You are setting boolean wrong.
And I think it is cleaner to control VisualTransformation above.

@Composable
fun PasswordTextField() {
    var masked by remember {
        mutableStateOf(false)
    }
    var password by remember {
        mutableStateOf("")
    }
    val visualTransformation by remember(masked) {
        if (masked)
            mutableStateOf(PasswordVisualTransformation())
        else
            mutableStateOf(VisualTransformation.None)
    }
            OutlinedTextField(
                value = password,
                onValueChange = { newText ->
                    password = newText
                },
                visualTransformation = visualTransformation,
                trailingIcon = {
                    if (masked) {
                        IconButton(onClick = {
                            masked = false
                        }) { Icon(imageVector = Icons.Filled.VisibilityOff, contentDescription = null) }
                    } else {
                        IconButton(onClick = { masked = true }) {
                            Icon(imageVector = Icons.Filled.Visibility, contentDescription = null)
                        }
                    }
                },

                label = { Text(text = "Password") },
                singleLine = true,
                modifier = Modifier
                    .fillMaxWidth(.1f),
            )
}

Upvotes: 2

Abhimanyu
Abhimanyu

Reputation: 14827

You have given revealPassword = true in both onClick().

Change the first one to revealPassword = false

Complete code

@Composable
fun TogglePassword() {
    val password = remember {
        mutableStateOf("")
    }
    var revealPassword: MutableState<Boolean> = remember {
        mutableStateOf(false)
    } // To reveal the password with toggle
    OutlinedTextField(
        value = password.value,
        onValueChange = { newText ->
            password.value = newText
        },
        visualTransformation = if (revealPassword.value) {
            VisualTransformation.None
        } else {
            PasswordVisualTransformation()
        },
        trailingIcon = {
            if (revealPassword.value) {
                IconButton(
                    onClick = {
                        revealPassword.value = false
                    },
                ) {
                    Icon(imageVector = Icons.Filled.Visibility, contentDescription = null)
                }
            } else {
                IconButton(
                    onClick = {
                        revealPassword.value = true
                    },
                ) {

                    Icon(imageVector = Icons.Filled.VisibilityOff, contentDescription = null)
                }
            }
        },
        label = {
            Text(text = "Password")
        },
        singleLine = true,
        leadingIcon = {
            Icon(imageVector = Icons.Default.Lock, contentDescription = null)
        },
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
    )
}

Upvotes: 3

Related Questions