Search code examples
androidandroid-jetpack-composeandroid-jetpack-compose-text

What is the simplest way to set the focus order in Jetpack Compose?


I have a column of TextFields, something like:

Column {
    TextField(
        value = ...,
        onValueChange = { ... },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.next),
    )
    TextField(
        value = ...,
        onValueChange = { ... },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.next),
    )
    .
    .
    .
}

I would like to have the focus on each TextField move to the next when the user press Tab, or the next button on the keyboard. Currently pressing Tab inserts a tab into the TextField. Pressing the next button does nothing. I can create a FocusRequester for each TextField and set the keyboardActions onNext to request focus on the next field for each one. This is a little tedious and it doesn't address the Tab behavior.


Solution

  • I recently found this article: https://medium.com/google-developer-experts/focus-in-jetpack-compose-6584252257fe

    It explains a different way to handle focus that is quite a bit simpler.

    val focusManager = LocalFocusManager.current
    TextField(
        modifier = Modifier
            .onPreviewKeyEvent {
                if (it.key == Key.Tab && it.nativeKeyEvent.action == ACTION_DOWN){
                    focusManager.moveFocus(FocusDirection.Down)
                    true
                } else {
                    false
                }
            },
        value = text,
        onValueChange = { it -> text = it },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
        keyboardActions = KeyboardActions(
            onNext = { focusManager.moveFocus(FocusDirection.Down) }
        )
    )