17

我正在使用 Jetpack compose 1.0.0-alpha07。我制作了一个登录屏幕,其中包含TextField使用其他可组合项自定义的两个 s。

但是,设置ImeAction似乎keyboardOptions不起作用。例如ImeAction.Next不将焦点移动到下一个 TextField。我认为我应该做一些事情来使它成为可能,但没有任何文件或文章曾简单地谈论过ImeOptions. 这是我的屏幕代码:

登录可组合:

EmailEdit(onChange = { email.value = it })
PasswordEdit(onChange = { password.value = it })

电子邮件编辑

@Composable
fun EmailEdit(onChange: (String) -> Unit) {
    val t = remember { mutableStateOf("") }
    TextField(
        value = t.value,
        onValueChange = { value ->
            t.value = value
            onChange(value)
        },
        leadingIcon = { Icon(asset = Icons.Default.Email) },
        label = { Text(text = "Email") },
        maxLines = 1,
        keyboardOptions = KeyboardOptions(
            imeAction = ImeAction.Next, // ** Go to next **
            keyboardType = KeyboardType.Email
        ),
        visualTransformation = VisualTransformation.None
    )
}      errorHint = "Not a valid email"
    )
}

通行证编辑

@Composable
fun PasswordEdit(onChange: (String) -> Unit) {
    val t = remember { mutableStateOf("") }
    TextField(
        value = t.value,
        onValueChange = { value ->
            t.value = value
            onChange(value)
        },
        leadingIcon = { Icon(asset = Icons.Default.Security) },
        label = { Text(text = "Password") },
        maxLines = 1,
        keyboardOptions = KeyboardOptions(
            imeAction = ImeAction.Done, // ** Done. Close the keyboard **
            keyboardType = KeyboardType.Text
        ),
        visualTransformation = PasswordVisualTransformation()
    )
}

要执行DoneNext我应该添加什么代码?

4

4 回答 4

26

1.0.x你可以使用

  • keyboardOptions:包含配置的软件键盘选项,例如KeyboardTypeImeAction
  • keyboardActions当输入服务发出 IME 操作时,会调用相应的回调

对于Done

您可以使用LocalSoftwareKeyboardController与键盘进行交互。

keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
    onDone = {keyboardController?.hide()}
)

对于Next

keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(
    onNext = { focusRequester.requestFocus() }
)

就像是:

val (focusRequester) = FocusRequester.createRefs()
val keyboardController = LocalSoftwareKeyboardController.current

TextField(
    value = text,
    onValueChange = {
        text = it
    },
    label = { Text("Label") },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
    keyboardActions = KeyboardActions(
        onNext = { focusRequester.requestFocus() } 
    )
)

TextField(
    value = text,
    onValueChange = {
        text = it
    },
    modifier = Modifier.focusRequester(focusRequester),
    label = { Text("Label") },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
    keyboardActions = KeyboardActions(
        onDone = { keyboardController?.hide() }
    )
)
于 2021-03-21T08:48:26.410 回答
12

使用onImeActionPerformed参数。

对于Done

TextField(
    onImeActionPerformed = { _, controller ->
        controller?.hideSoftwareKeyboard()
    }
)

对于Next

val focusRequester = remember { FocusRequester() }
TextField(
    onImeActionPerformed = { _, _ ->
        focusRequester.requestFocus()
    }
)
TextField(
    modifier = Mofifier.focusRequester(focusRequester)
)

这是一个工作示例:

val focusRequester = remember { FocusRequester() }
val email = remember { mutableStateOf("") }
TextField(
    value = email.value,
    onValueChange = { email.value = it },
    imeAction = ImeAction.Next,
   onImeActionPerformed = { _, _ -> focusRequester.requestFocus() }
)
val password = remember { mutableStateOf("") }
TextField(
    value = password.value,
    onValueChange = { password.value = it },
    imeAction = ImeAction.Done,
    onImeActionPerformed = { _, controller -> controller?.hideSoftwareKeyboard() },
    modifier = Modifier.focusRequester(focusRequester)
)

文档:

于 2020-11-22T08:40:46.603 回答
11

您可以使用LocalFocusManager

val localFocusManager = LocalFocusManager.current

您的字段的内部父级可组合。

将焦点移动到下一个字段:

localFocusManager.moveFocus(FocusDirection.Down)

在 KeyboardActions 的 onNext 内将焦点移到特定方向,例如左、右、上和下。

清除焦点:

localFocusManager.clearFocus()

KeyboardActions的onDone内清除焦点。

电子邮件字段:

OutlinedTextField(
            value = userId,
            onValueChange = { userId = it },
            label = { Text("Email") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            leadingIcon = {
                Icon(
                    painter = painterResource(id = R.drawable.ic_account),
                    contentDescription = "ID"
                )
            },
            colors = TextFieldDefaults.outlinedTextFieldColors(
                focusedBorderColor = Color.Gray,
                unfocusedBorderColor = Color.LightGray,
                focusedLabelColor = Color(0xffcc0000)
            ),
            keyboardOptions =
            KeyboardOptions(
                keyboardType = KeyboardType.Text,
                imeAction = ImeAction.Next
            ),
            keyboardActions = KeyboardActions(onNext = {
                localFocusManager.moveFocus(FocusDirection.Down)
            })
        )

密码字段:

OutlinedTextField(
            value = password,
            onValueChange = { password = it },
            label = { Text("Password") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            leadingIcon = {
                Icon(
                    painter = painterResource(id = R.drawable.ic_password),
                    contentDescription = "Password"
                )
            },
            colors = TextFieldDefaults.outlinedTextFieldColors(
                focusedBorderColor = Color.Gray,
                unfocusedBorderColor = Color.LightGray,
                focusedLabelColor = Color(0xffcc0000)
            ),
            keyboardOptions =
            KeyboardOptions(
                keyboardType = KeyboardType.Password,
                imeAction = ImeAction.Done
            ),
            keyboardActions = KeyboardActions(onDone = {
                localFocusManager.clearFocus()
            })

        )

试过版本1.0.1

于 2021-08-11T13:31:02.437 回答
4

在本例中使用 Compose,您需要为屏幕上的每个可聚焦文本字段创建一组引用,如下所示(textField1、textField2)并获取对键盘控制器的引用。

然后,您可以在键盘选项中添加一种操作类型,指示显示键盘时操作按钮的外观。

在keyboardActions 参数中,您可以在指定的IME 操作上调用一个函数——在这种情况下,我已经声明我希望textField2 在按下键盘操作按钮时获得焦点。您在 TextField 的 Modifier.focusRequester 参数中分配引用。

最后,为了让您的第一个 TextField 在屏幕出现时获得焦点,您调用 DisposableEffect 函数,您可以在其中指定您希望 textField1 在屏幕首次显示时获得焦点。

val (textField1, textField2) = remember { FocusRequester.createRefs() }
val keyboardController = LocalSoftwareKeyboardController.current

TextField(
    modifier = Modifier.focusRequester(textField1),
    keyboardOptions  = KeyboardOptions(imeAction = ImeAction.Next),
    keyboardActions = KeyboardActions( onNext = {textField2.requestFocus()}
   ),
)


 TextField(
    modifier = Modifier.focusRequester(textField2),
    keyboardOptions  = KeyboardOptions(imeAction = ImeAction.Done),
    keyboardActions = KeyboardActions( onDone = { 
    keyboardController?.hide()}
   ),
)

DisposableEffect(Unit) {
    textField1.requestFocus()
    onDispose { }
}
于 2021-07-27T14:37:19.900 回答