I'm using TextField component in Jetpack Compose. How to select all text when it receive focus?
To read value entered in TextField in Android Compose, declare a variable, and assign this variable the value in the TextField whenever there is a change in the value. The same process holds for reading value entered in OutlineTextField composable.
To change color of Text composable in Android Jetpack Compose, pass a required Color value for the optional color parameter of Text composable.
In this case you should use TextFieldValue as state of your TextField, and when it receive focus, you set the selection using the TextFieldValue state.
val state = remember {
mutableStateOf(TextFieldValue(""))
}
TextField(
value = state.value,
onValueChange = { text -> state.value = text },
modifier = Modifier
.onFocusChanged { focusState ->
if (focusState.isFocused) {
val text = state.value.text
state.value = state.value.copy(
selection = TextRange(0, text.length)
)
}
}
)
Here's the result:

Notice that depending on you're touching the cursor goes to the touched position instead of select the entire text. You can try to figure it out if this is a bug or a feature :)
@nglauber solution doesn't seems to work anymore.
Debugging shows that onFocusChanged is called before onValueChange and within one view life cycle. A selection changed during onFocusChanged has no effect on TextField, since it is overridden during onValueChange.
Here's a possible workaround:
var state by remember {
mutableStateOf(TextFieldValue("1231"))
}
var keepWholeSelection by remember { mutableStateOf(false) }
if (keepWholeSelection) {
// in case onValueChange was not called immediately after onFocusChanged
// the selection will be transferred correctly, so we don't need to redefine it anymore
SideEffect {
keepWholeSelection = false
}
}
TextField(
value = state,
onValueChange = { newState ->
if (keepWholeSelection) {
keepWholeSelection = false
state = newState.copy(
selection = TextRange(0, newState.text.length)
)
} else {
state = newState
}
},
modifier = Modifier
.onFocusChanged { focusState ->
if (focusState.isFocused) {
val text = state.text
state = state.copy(
selection = TextRange(0, text.length)
)
keepWholeSelection = true
}
}
)
I think it should be possible to make it easier, so I created this question on Compose issue tracker.
I didn't have 100% success with @nglauber answer. You should add a small delay and it works great. For example:
val state = remember {
mutableStateOf(TextFieldValue(""))
}
// get coroutine scope from composable
val scope = rememberCoroutineScope()
TextField(
value = state.value,
onValueChange = { text -> state.value = text },
modifier = Modifier
.onFocusChanged {
if (it.hasFocus) {
// start coroutine
scope.launch {
// add your preferred delay
delay(10)
val text = state.value.text
state.value = state.value.copy(
selection = TextRange(0, text.length)
)
}
}
}
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With