I want to create such Textfield:
how to do it, the textfield background?
You can use a TextField
and format the number with the visualTransformation
property:
TextField(value = text,
onValueChange = { text = it },
visualTransformation = NumberTransformation()
)
where NumberTransformation
is something like:
class NumberTransformation() : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
return numberFilter(text)
}
}
fun numberFilter(text: AnnotatedString): TransformedText {
// +XXX XXX XXX XXX
val trimmed = if (text.text.length >= 12) text.text.substring(0..11) else text.text
var out = ""
for (i in trimmed.indices) {
if (i==0) out += "+"
out += trimmed[i]
if (i % 3 == 2 && i != 11) out += " "
}
val numberOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 0) return offset
if (offset <= 2) return offset +1
if (offset <= 5) return offset +2
if (offset <= 8) return offset +3
if (offset <= 12) return offset +4
return 16
}
override fun transformedToOriginal(offset: Int): Int {
if (offset <=0) return offset
if (offset <=3) return offset -1
if (offset <=7) return offset -2
if (offset <=11) return offset -3
if (offset <=15) return offset -4
return 11
}
}
return TransformedText(AnnotatedString(out), numberOffsetTranslator)
}
For a North American Number:
const val mask = "(xxx) xxx-xxxx"
fun mobileNumberFilter(text: AnnotatedString): TransformedText {
// change the length
val trimmed =
if (text.text.length >= 14) text.text.substring(0..13) else text.text
val annotatedString = AnnotatedString.Builder().run {
for (i in trimmed.indices) {
val trimmedPortion = trimmed[i]
if (i == 0) {
append("($trimmedPortion")
} else {
append(trimmedPortion)
}
if (i == 2) {
append(") ")
}
if (i == 5) {
append("-")
}
}
pushStyle(
SpanStyle(color = Color.LightGray)
)
append(mask.takeLast(mask.length - length))
toAnnotatedString()
}
val translator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 1) return offset
if (offset <= 4) return offset + 1
if (offset <= 9) return offset + 2
return 14
}
override fun transformedToOriginal(offset: Int): Int {
if (offset <= 1) return offset
if (offset <= 4) return offset - 1
if (offset <= 9) return offset - 2
return 14
}
}
return TransformedText(annotatedString, translator)
}