So i’m trying to implement the top answer in this thread
as well as follow along with the following video
The app builds fine, but as soon as I click the TextField to begin inserting data the app crashes with the following error (the stack trace is far too big to copy in I think)
java.lang.IllegalStateException: OffsetMapping.transformedToOriginal returned invalid mapping: 12 -> 10 is not in range of original text [0, 0]
I simply cannot see where the issue lies as there is basically no deviation from the examples given apart from small alterations to the mask and offset to suit the format I am going for. But as far as I can see these should be ok. My code sample is as follows.
@Composable
fun DisplayPhoneNumberTextField() {
var mobileNo by remember {
mutableStateOf("")
}
OutlinedTextField(
value = mobileNo,
onValueChange = { mobileNo = it},
modifier = Modifier.fillMaxWidth(),
placeholder = {
Text(text = "Phone Number")
},
singleLine = true,
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = MaterialTheme.colors.secondary
),
visualTransformation = {
phoneNumberInputFormatter(it)
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
)
}
private fun phoneNumberInputFormatter(text : AnnotatedString) : TransformedText {
val mask = "xxx-xxx-xxxx"
val trimmed = if(text.text.length >= 10) text.text.substring(0..9) else text.text
val annotatedString = AnnotatedString.Builder().run {
for (i in trimmed.indices){
append(trimmed[i])
if (i == 2 || i == 5){
append("-")
}
}
pushStyle(SpanStyle(color = Color.LightGray))
append(mask.takeLast(mask.length - length))
toAnnotatedString()
}
val phoneNumberOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 5) return offset + 1
if (offset <= 9) return offset + 2
return 12
}
override fun transformedToOriginal(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 5) return offset - 1
if (offset <= 9) return offset - 2
return 10
}
}
return TransformedText(annotatedString, phoneNumberOffsetTranslator)
}
Any help would be much appreciated
2
Answers
Looks like possible duplicate of this: Fatal Exception: java.lang.IllegalArgumentException offset(23) is out of bounds [0, 0] JetPack Compose OutlinedTextField
i.e., input is empty when mapping is done
Maybe you can try returning
TransformedText
like this instead of custom transformation:Or, you can try solutions provided in above like i.e., return
OffsetMapping.Identity
when input is empty andcustomMapping
when there is input@murphler, I could be wrong here, but I think your mask variable is getting added to the total length which is why it’s offset it crashing. Try making
mask = ""
and see if that helps.