I have a textfield and trying to achieve something like
I am trying to do this with visual transformation but running into issues.
when I edit seems error like offsetmapping.originaltotransformed returned invalid mapping:
Anyone knows how can I achieve this ?
class UserNameMaskTransformation() : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
return maskFilter(text)
}
}
fun maskFilter(text: AnnotatedString): TransformedText {
var maskLen = 4
var maskChar = "*"
val maskingChars = AnnotatedString(maskChar.repeat(maskLen))
val subString = AnnotatedString(text.substring(4))
return TransformedText(maskingChars + subString, OffsetMapping.Identity)
}
You can use the onFocusChanged
callback to determine the current focus and apply the relevant transformation.
@Composable
fun TextFieldMaskTest() {
var hasFocus by remember {
mutableStateOf(false)
}
var text by remember { mutableStateOf("johndoe") }
Column {
TextField(
modifier = Modifier
.onFocusChanged { hasFocus = it.isFocused },
value = text,
onValueChange = {
text = it
},
visualTransformation = if (hasFocus) {
VisualTransformation.None
} else {
MaskingTransformation()
}
)
TextField(value = "", onValueChange = {})
}
}
Update your transformation class to handle the text length properly (as suggested by the @Abdo21)
class MaskingTransformation : VisualTransformation {
private val maskLen = 4
private val maskChar = "*"
override fun filter(text: AnnotatedString): TransformedText {
val maskLengthToUse = minOf(maskLen, text.text.length)
return TransformedText(
AnnotatedString(maskChar.repeat(maskLengthToUse) + text.text.substring(maskLengthToUse)),
OffsetMapping.Identity
)
}
}