Jetpack Compose: Focus manager
9th June 2022
Focus manager allows us to focus/traverse input fields in a linear or non-linear way when pressing the "next" button on the device's keyboard.
Jamie Sanson wrote a good post on it here which covers some additional features. I found that late into writing my example code and was too lazy to modify what I'd planned to write.
You can find my full example code here.
Focus modifiers
You can define a custom focus requester as seen below with secondNameFocusRequester
. The focus requester
is passed in the modifier to the field which will be focused - in this case the field for second name. Then in the keyboard actions of
the TextField we trigger the call when the user presses the next button.
@Composable
fun FormContent(modifier: Modifier) {
val secondNameFocusRequester = remember { FocusRequester() }
//First name
FormTextField(..
onNextClicked = {secondNameFocusRequester.requestFocus()})
//Second name
FormTextField(..
modifier = Modifier.focusRequester(secondNameFocusRequester))
}
@Composable
fun FormTextField(
modifier: Modifier
onNextClicked: () -> Unit) {
TextField(..
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(onNext = {onNextClicked()})
)
}
Focus manager
Alternatively you can get a reference of the current focus manager and make use of the methods on that. In the below examples
you can see it used to move Down
to the next item in the list, and also clearFocus
which is going to hide the keyboard for us. Useful to help bring a form button into view for example.
@Composable
fun FormContent(modifier: Modifier) {
val focusManager = LocalFocusManager.current
//Address 1
FormTextField(
modifier = Modifier.focusRequester(address1FocusRequester),
value = "",
label = "Address 1",
onNextClicked = {focusManager.moveFocus(FocusDirection.Down)})
//Address 2
FormTextField(
modifier = Modifier.focusRequester(address2FocusRequester),
value = "",
label = "Address 2",
onNextClicked = {focusManager.clearFocus()})
}
Focus on entry to screen
To focus on a field when you enter the screen, you can use a focus modifier along with a LaunchedEffect
to bring attention to the first form field straight away.
@Composable
fun FormContent(modifier: Modifier) {
val firstNameFocusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
//First name
FormTextField(
modifier = Modifier.focusRequester(firstNameFocusRequester),
..)
LaunchedEffect(Unit) {
firstNameFocusRequester.requestFocus()
}
}