Bradleycorn
09/20/2021, 7:47 PMTextField value and State.
Can someone explain why, given the following composable:
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = { newText ->
Log.d("TEXTFIELD", "NewText: $newText")
val editedText = newText.replace(Regex("\\D"), "")
if (editedText.startsWith("1"))
text = editedText
}
)
If I type the number 5 into the text field four times, the result I see in LogCat is:
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 55
D/TEXTFIELD: NewText: 5
I’m stumped?Bradleycorn
09/20/2021, 7:54 PMD/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 4
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 4Stylianos Gakis
09/20/2021, 8:40 PMBradleycorn
09/20/2021, 8:41 PMBradleycorn
09/20/2021, 8:42 PMD/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 55
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 55
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 55
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 55Bradleycorn
09/20/2021, 8:44 PMD/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 5
D/TEXTFIELD: NewText: 54Sean McQuillan [G]
09/20/2021, 9:56 PMSean McQuillan [G]
09/20/2021, 9:57 PMSean McQuillan [G]
09/20/2021, 9:57 PMBradleycorn
09/20/2021, 9:59 PMSean McQuillan [G]
09/20/2021, 9:59 PMBradleycorn
09/21/2021, 12:18 AMRick Regan
09/29/2021, 2:01 AMKeyboardType.Number) to remove leading 0s but they keep accumulating. (The issue above has 10 stars but is still marked 'new'.)Sean McQuillan [G]
09/29/2021, 2:55 AMRick Regan
09/29/2021, 1:10 PMit every time. I was initially stripping off the first leading 0 thinking it could never then be more than one 0 (I had assumed it was value plus the new character). Instead now I do this (I also remove any non-numeric character from the Number keyboard) and it seems to work:
value = text,
onValueChange = {
text = it.replace(Regex("^0*"),"")
text = text.replace(Regex("[ ]"),"")
text = text.replace(Regex("[-]"),"")
text = text.replace(Regex("[,]"),"")
text = text.replace(Regex("[.]"),"")
println("it = \"$it\", text = \"$text\"")
},
The value if it is still curious though, as per the bug I guess. It is as I expect except for leading 0s -- it retains every leading 0 typed. For example, after typing five 0s, this prints it = "00000", text = "". Typing another digit after that (say 9) it prints it = "000009", text = "9". Typing yet another digit (say 8) it prints it = "98", text = "98".
text is still correct, which is what really matters I guess.
Thanks for clearing this up for me (now I know why it's low severity, despite the interest).Sean McQuillan [G]
09/29/2021, 4:28 PMRick Regan
09/29/2021, 4:54 PMSean McQuillan [G]
09/29/2021, 4:54 PMSean McQuillan [G]
09/29/2021, 4:54 PMSean McQuillan [G]
09/29/2021, 4:54 PMonValueChange. This may happen, for example, if the user uses
autocorrect, replaces a word with an emoji, or other smart editing features. To
correctly handle this, write any transformation logic with the assumption that
the current text passed to onValueChange is unrelated to the previous or next
values that will be passed to onValueChange.
To implement a text field that disallows leading zeros, you can do this by
stripping all leading zeroes on every value change.
kotlin
@Composable
fun NoLeadingZeroes() {
val input by rememberSavable { mutableStateOf("") }
TextField(
value = input
onValueChange = { newText ->
text = newText.trimStart { it == '0' }
}
)
}
To control the cursor position while cleaning text, use the TextFieldValue
overload of TextField instead of passing a regular string. This overload
allows you to change the cursor position as part of the state.Sean McQuillan [G]
09/29/2021, 4:55 PMRick Regan
09/29/2021, 4:58 PMSean McQuillan [G]
09/29/2021, 5:41 PMBradleycorn
11/17/2021, 8:31 PM@Composable
fun LimitedTextField(maxLength: Int) {
var text by remember { mutableStateOf("") }
TextField(value = text, onValueChange = { new ->
val filteredText = new.take(maxLength)
text = filteredText
})
}
If you call it with maxLength = 5, and then type “abcdefg” it will show “g”, instead of “abcde”.Sean McQuillan [G]
11/18/2021, 7:36 PMBradleycorn
11/19/2021, 4:56 PMonValueChange callback is not correct. So it’s possible that whatever is calculating the value that gets passed to onValueChange has a defect, and when that is fixed, it could conceivably fix both of these issuesRick Regan
11/19/2021, 5:08 PMBradleycorn
11/19/2021, 5:11 PM