3

I want to create such Textfield:

enter image description here

how to do it, the textfield background?

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Nurseyit Tursunkulov
  • 8,012
  • 12
  • 44
  • 78

2 Answers2

4

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)
}

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
0

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)
}
Kristy Welsh
  • 7,828
  • 12
  • 64
  • 106
  • My keyboard type is number ...if i enter . (dot)(say special character).. app is crashing getting java.lang.IllegalArgumentException: offset(1) is out of bounds [0, 0] compose – Gaju Kollur Dec 23 '22 at 10:36