Issue
How to move focus from Compose Button to Compose TextField
by using the arrow key?
When I have moved focus from Compose Button to Compose TextField
by using the arrow key(KeyEvent.KEYCODE_DPAD_UP
),
the focus moves twice for that key press. (when I use page-up-key)
I hope that the focus moves once for that key press.
Please see GIF animation for details
Is there a way to fix this?
(I use up-key and down-key in moving between TextFields
using moveFocus
method of focusManager
in onKeyEvent
)
@Composable
fun Screen() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
val focusManager = LocalFocusManager.current
FocusMoveTextField(focusManager)
FocusMoveTextField(focusManager)
FocusMoveTextField(focusManager)
OutlinedButton(
onClick = {}
) {
Text("Button")
}
}
}
@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
)
)
}
Solution
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
)
)
}
Answered By - Linh
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.