9

我有一列TextFields,例如:

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

当用户按 Tab 或键盘上的下一个按钮时,我希望将每个 TextField 上的焦点移到下一个。当前按 Tab 会在 TextField 中插入一个选项卡。按下一个按钮没有任何作用。我可以为每个 TextField 创建一个 FocusRequester 并设置 keyboardActions onNext 以请求将焦点放在每个 TextField 的下一个字段上。这有点乏味,并且没有解决 Tab 行为。

4

5 回答 5

6

不确定这是否更简单,但您可以FocusRequester为每个字段创建一个对象并按照您想要的顺序请求焦点。

@Composable
fun FocusRequestScreen() {
    // Create FocusRequesters... (you can use createRefs function)
    val focusRequesters = List(3) { FocusRequester() }

    Column {
        TextFieldWithFocusRequesters(focusRequesters[0], focusRequesters[1])
        TextFieldWithFocusRequesters(focusRequesters[1], focusRequesters[2])
        TextFieldWithFocusRequesters(focusRequesters[2], focusRequesters[0])
    }
}

@Composable
private fun TextFieldWithFocusRequesters(
    focusRequester: FocusRequester,
    nextFocusRequester: FocusRequester
) {
    var state by rememberSaveable {
        mutableStateOf("Focus Transition Test")
    }
    TextField(
        value = state,
        onValueChange = { text -> state = text },
        // Here it is what you want...
        modifier = Modifier
            .focusOrder(focusRequester) {
                nextFocusRequester.requestFocus()
            }
        ,
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next)
    )
}

我从这里得到这个代码。虽然它并没有解决标签问题...... :(

于 2021-03-26T15:17:55.770 回答
4

我最近发现了这篇文章:https ://medium.com/google-developer-experts/focus-in-jetpack-compose-6584252257fe

它解释了一种更简单的处理焦点的不同方法。

val focusManager = LocalFocusManager.current
TextField(
    modifier = Modifier
        .onPreviewKeyEvent {
            if (it.key == Key.Tab){
                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) }
    )
)
于 2021-08-31T13:10:16.230 回答
4

我目前在compose_version = '1.0.2'

按下下一个按钮时焦点不会移动,因为虽然默认的键盘操作是将焦点移到下一个按钮,但compose 似乎不知道下一个应该是哪一个。FocusRequester 为每个项目创建s 并通过设置它们的焦点顺序可以工作(顺便说一句,如果您选择这种方式,则Modifier.focusOrder() {}无需设置keyboardActionss来请求焦点),但由于您的 s 是相同的,您可以设置为告诉 compose将焦点移到向下的那个。就像是:onNextTextFieldColumnkeyboardActions

        Column {
            val focusManager = LocalFocusManager.current
            TextField(
                value = "", onValueChange = {},
                keyboardOptions = KeyboardOptions( imeAction = ImeAction.Next ),
                keyboardActions = KeyboardActions(
                    onNext = { focusManager.moveFocus(FocusDirection.Down) }
                )
            )
            TextField(
                value = "", onValueChange = {},
                keyboardOptions = KeyboardOptions( imeAction = ImeAction.Next ),
                keyboardActions = KeyboardActions(
                    onNext = { focusManager.moveFocus(FocusDirection.Down) }
                )
            )
            TextField(
                value = "", onValueChange = {},
                keyboardOptions = KeyboardOptions( imeAction = ImeAction.Next ),
                keyboardActions = KeyboardActions(
                    onNext = { focusManager.moveFocus(FocusDirection.Down) }
                )
            )
        }

完成此操作后,IME 键盘上的下一个按钮应该可以使用。

对于Tab键,因为TextField不会Tab自动处理键,所以您可能希望使用focusManagerinsideModifier.onKeyEvent{}以与上述示例相同的方式移动焦点。

于 2021-09-26T16:34:50.130 回答
3

关于订单,您可以查看@nglauber 答案

要使用 Tab 键,您可以使用onKeyEvent修饰符

TextField(
    modifier = Modifier
        .focusRequester(focusRequester)
        .onKeyEvent {
            if (it.key.keyCode == Key.Tab.keyCode){
                focusRequesterNext.requestFocus()
                true //true -> consumed
            } else false },
    value = text,
    onValueChange = { it -> text = it },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
    keyboardActions = KeyboardActions(
        onNext = {focusRequesterNext.requestFocus()}
        )
)
于 2021-03-26T16:28:11.170 回答
0

设置 singleLine ,请尝试

OutlinedTextField(
...
singleLine = true,
)

简单的例子

@Composable
fun Test() {
    val focusManager = LocalFocusManager.current
    var text1 by remember {
        mutableStateOf("")
    }
    var text2 by remember {
        mutableStateOf("")
    }
    Column() {
        OutlinedTextField(value = text1, onValueChange = {
            text1 = it
        },
            keyboardOptions = KeyboardOptions(
                imeAction = ImeAction.Next,
                keyboardType = KeyboardType.Text
            ),
            keyboardActions = KeyboardActions(
                onNext ={
                    focusManager.moveFocus(FocusDirection.Down)
                }
            ),
            singleLine = true
            )
        OutlinedTextField(value = text2, onValueChange = {
            text2 = it
        },
            keyboardOptions = KeyboardOptions(
                imeAction = ImeAction.Next,
                keyboardType = KeyboardType.Text
            ),
            keyboardActions = KeyboardActions(
                onNext ={
                    focusManager.moveFocus(FocusDirection.Down)
                }
            ),
            singleLine = true
        )
    }
}
于 2022-02-25T05:36:59.873 回答