diff --git a/tutorials/Tab_Navigation/README.md b/tutorials/Tab_Navigation/README.md index 3251aa68a6..cf204b129d 100644 --- a/tutorials/Tab_Navigation/README.md +++ b/tutorials/Tab_Navigation/README.md @@ -309,3 +309,74 @@ fun main() = application { ``` reverse-order + +## Known problems + +### Tab key navigation doesn't work in a multiline TextField +``` Kotlin +Column { + repeat(5) { + var text by remember { mutableStateOf("Hello, World!") } + + OutlinedTextField( + value = text, + singleLine = false, // Pay attention here! Also, by default, singleLine is false. + onValueChange = { text = it }, + modifier = Modifier.padding(8.dp) + ) + } +} +``` +When the user presses the 'Tab' key, the focus doesn't switch to the next focusable component. Instead the Tab character is added. + +#### A possible workaround + +This workaround is mentioned in [Issues/109](https://github.com/JetBrains/compose-jb/issues/109#issuecomment-1161705265). +Write a custom Modifier.moveFocusOnTab: +```Kotlin +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material.OutlinedTextField +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.input.key.* +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.singleWindowApplication + +fun main() = singleWindowApplication { + Column { + repeat(5) { + var text by remember { mutableStateOf("Hello, World!") } + + OutlinedTextField( + value = text, + singleLine = false, // Pay attention here! Also, by default, singleLine is false. + onValueChange = { text = it }, + modifier = Modifier.padding(8.dp).moveFocusOnTab() + ) + } + } +} + +@OptIn(ExperimentalComposeUiApi::class) +fun Modifier.moveFocusOnTab() = composed { + val focusManager = LocalFocusManager.current + onPreviewKeyEvent { + if (it.type == KeyEventType.KeyDown && it.key == Key.Tab) { + focusManager.moveFocus( + if (it.isShiftPressed) FocusDirection.Previous else FocusDirection.Next + ) + true + } else { + false + } + } +} +```