18

I want my Textfield to be prefixed with a country code (+91), which can't be changed by the user. How do I achieve this?

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Sparsh Dutta
  • 2,450
  • 4
  • 27
  • 54

3 Answers3

33

With M3 TextField,starting from 1.1.0-alpha06 you can use the prefix attribute:

    //androidx.compose.material3
    TextField( 
        value = text,
        onValueChange = { text = it },
        prefix = { Text ("+91") }
    )

enter image description here

Before M3 1.1.0-alpha06 or with M2 or you can use the visualTransformation property:

Something like:

TextField(
    value = text,
    onValueChange = { text = it},
    visualTransformation = PrefixTransformation("(+91)")
)

with:

class PrefixTransformation(val prefix: String) : VisualTransformation {    
    override fun filter(text: AnnotatedString): TransformedText {
        return PrefixFilter(text, prefix)
    }
}

fun PrefixFilter(number: AnnotatedString, prefix: String): TransformedText {

    var out = prefix + number.text
    val prefixOffset = prefix.length

    val numberOffsetTranslator = object : OffsetMapping {
        override fun originalToTransformed(offset: Int): Int {
            return offset + prefixOffset
        }

        override fun transformedToOriginal(offset: Int): Int {
            if (offset < prefixOffset) return 0
            return offset - prefixOffset
        }
    }

    return TransformedText(AnnotatedString(out), numberOffsetTranslator)
}

enter image description here

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

You can simply add Text() inside leadingIcon parameter inside textField

OutlinedTextField(
    value = text,
    onValueChange = onTextChange,
    maxLines = 1,
    leadingIcon =
    {
        Text(
            text = prefixText,
            style = textStyle,
            color = Color.Black,
            modifier = Modifier.padding(start = 24.dp, end = 8.dp)
        )
    }
)
Amr
  • 1,068
  • 12
  • 21
  • This is quite nice solution in case there is no need to change the leadingIcon content dynamically. Changing it dynamically changes also the space in between the value and the leadingIcon du to alignment of the leading icon. And it looks clunky in this scenario. – kotoMJ Feb 13 '23 at 09:04
0

Another option you could use as well as Gabriele's answer is using the leadingIcon property of TextField

TextField(
    value = text,
    onValueChange = { text = it},
    leadingIcon = {
                Icon(
                    painter = painterResource(id = R.drawable.ic_pound_symbol),
                    contentDescription = null,
                    tint = colorResourceFromAttr(id = R.attr.colorOnSurface)
                )
            }
)

Which gives you this:

a jetpack compose textfield with pound symbol prefix

MichaelStoddart
  • 5,571
  • 4
  • 27
  • 49