android - 如何使用箭头键将焦点从撰写按钮移动到撰写文本字段?

标签 android kotlin android-jetpack-compose android-jetpack

如何将焦点从撰写按钮转移到撰写 TextField通过使用箭头键?
当我将焦点从撰写按钮移至撰写时 TextField通过使用箭头键(KeyEvent.KEYCODE_DPAD_UP),
该按键的焦点移动两次。
(当我使用翻页键时)
我希望焦点在那个按键上移动一次。
详情请看GIF动画
有没有办法来解决这个问题?
(我在 TextFields 之间移动时使用向上键和向下键
使用 moveFocus focusManager的方法在 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
        )
    )
}

最佳答案

测试后我看到 onKeyEventButton 上按一个键后会触发 2 次(ACTION_DOWN 为 1,ACTION_UP 为 1)。也许它会导致按键时焦点移动两次。
那么我认为你可以专注于你的 Button喜欢

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)
}
完整示例
@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
        )
    )
}

关于android - 如何使用箭头键将焦点从撰写按钮移动到撰写文本字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70669774/

相关文章:

android - 在 Espresso 测试中更改辅助功能字体大小和显示大小

Kotlin - 相同条件 : multiple if statements or one if statement

kotlin - 在 Swift 中使用协程流

android - Jetpack Compose 中一个 ModalBottomSheetLayout 的多个 BottomSheet

android - 重叠两个 Box jetpack 组合

android - 谷歌地图 fragment 在 N​​estedScrollView 内滚动

java - 如何将Drawable(ripple-drawable)设置为跨度的背景?

android - 如何在 TopAppBar 的布局中心对齐标题?

android - Flutter:WAITING另一个flutter命令释放启动锁

android - 回收站 View : disable scroll if there is enough room for all items