I’m having an issue with my text field icon that’s nested in the decorator. It’s not being updated when isPasswordVisible changes. However, the obfuscation part is updated when isPasswordVisible changes. I put logs right before the IconButton and it doesn’t get reached when isPasswordVisible changes.
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun PasswordTextField(
state: TextFieldState,
isPasswordVisible: Boolean,
onTogglePasswordVisibility: () -> Unit,
hint: String,
title: String?,
modifier: Modifier = Modifier
) {
var isFocused by remember {
mutableStateOf(false)
}
Column(
modifier = modifier
) {
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
if (title != null) {
Text(
text = title,
style = MaterialTheme.typography.titleSmall,
)
}
}
Spacer(modifier = Modifier.height(4.dp))
BasicSecureTextField(
state = state,
textObfuscationMode = if (isPasswordVisible) {
TextObfuscationMode.Visible
} else TextObfuscationMode.Hidden,
textStyle = LocalTextStyle.current.copy(
color = MaterialTheme.colorScheme.onBackground
),
cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground),
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(
MaterialTheme.colorScheme.surface
)
.border(
width = 1.dp,
color = Color.Transparent,
shape = RoundedCornerShape(16.dp)
)
.padding(12.dp)
.onFocusChanged {
isFocused = it.isFocused
},
decorator = { innerBox ->
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = PasswordIcon,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.width(16.dp))
Box(
modifier = Modifier
.weight(1f)
) {
if (state.text.isEmpty() && !isFocused) {
Text(
text = hint,
color = MaterialTheme.colorScheme.onSurface.copy(
alpha = 0.4f
),
modifier = Modifier.fillMaxWidth()
)
}
innerBox()
}
IconButton(
onClick = onTogglePasswordVisibility,
modifier = Modifier.height(24.dp)
) {
Icon(
imageVector = if (isPasswordVisible) {
EyeOpenIcon
} else {
EyeCloseIcon
},
contentDescription = if (isPasswordVisible) {
stringResource(id = R.string.show_password)
} else {
stringResource(id = R.string.hide_password)
},
tint = MaterialTheme.colorScheme.onSurface
)
}
}
}
)
}
}