How to move focus from Compose Button to Compose TextField by using the arrow key?
Solution 1:
After testing I see that onKeyEvent
will fired 2 times after press a key on Button
(1 for ACTION_DOWN
and 1 for ACTION_UP
). Maybe it cause the focus move twice when press a key.
Then I think you can handle focus on your Button
like
val focusRequester = remember { FocusRequester() }
var buttonColor by remember { mutableStateOf(Black) }
OutlinedButton(
onClick = { focusRequester.requestFocus() }, modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged { buttonColor = if (it.isFocused) Green else Black }
.focusTarget()
.onKeyEvent { keyEvent ->
if (keyEvent.nativeKeyEvent.action == ACTION_UP) {
when (keyEvent.nativeKeyEvent.keyCode) {
KEYCODE_DPAD_DOWN -> {
focusManager.moveFocus(FocusDirection.Down)
true
}
KEYCODE_DPAD_UP -> {
focusManager.moveFocus(FocusDirection.Up)
true
}
else -> {
false
}
}
} else {
true
}
}
) {
Text("Button", color = buttonColor)
}
Complete example
@Composable
fun Screen() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
val focusManager = LocalFocusManager.current
FocusMoveTextField(focusManager)
FocusMoveTextField(focusManager)
FocusMoveTextField(focusManager)
val focusRequester = remember { FocusRequester() }
var buttonColor by remember { mutableStateOf(Black) }
OutlinedButton(
onClick = { focusRequester.requestFocus() }, modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged { buttonColor = if (it.isFocused) Green else Black }
.focusTarget()
.onKeyEvent { keyEvent ->
if (keyEvent.nativeKeyEvent.action == ACTION_UP) {
when (keyEvent.nativeKeyEvent.keyCode) {
KEYCODE_DPAD_DOWN -> {
focusManager.moveFocus(FocusDirection.Down)
true
}
KEYCODE_DPAD_UP -> {
focusManager.moveFocus(FocusDirection.Up)
true
}
else -> {
false
}
}
} else {
true
}
}
) {
Text("Button", color = buttonColor)
}
FocusMoveTextField(focusManager)
FocusMoveTextField(focusManager)
}
}
@Composable
private fun FocusMoveTextField(
focusManager: FocusManager
) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.onKeyEvent { keyEvent ->
when (keyEvent.nativeKeyEvent.keyCode) {
KEYCODE_DPAD_DOWN -> {
focusManager.moveFocus(FocusDirection.Down)
true
}
KEYCODE_DPAD_UP -> {
focusManager.moveFocus(FocusDirection.Up)
true
}
else -> {
false
}
}
},
value = "",
onValueChange = {},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
)
)
}