未分类 · 2022年10月28日 0

Jetpack Compose 中的键盘处理——所有你需要知道的

内容纲要

原文链接:https://blog.canopas.com/keyboard-handling-in-jetpack-compose-all-you-need-to-know-3e6fddd30d9a

无论您是初学者还是经验丰富的开发人员,您都会发现自己在处理键盘 API。这是掌握它的指南。

Jetpack Compose 中的键盘处理——所有你需要知道的
Jetpack compose 中的键盘处理

在本文中,我们将学习在 Jetpack compose 中管理键盘的重要用例。

我们将介绍:

1.如何隐藏和显示软键盘。

2. 键盘出现时如何调整布局。

3. 键盘动作

4. 键盘选项

5.如何检测键盘?

让我们开始吧!

1.如何隐藏和显示软键盘

当我们点击 TextField 时,键盘会弹出,输入文本后,我们想关闭键盘。

a. KeyboardController

在 jetpack compose 中,我们有LocalSoftwareKeyboardControllerAPI 来控制键盘的可见性。此 API 被标记为 ExperimentalComposeUiApi,因此将来可能会更改。

val keyboardController = LocalSoftwareKeyboardController.current
//To hide keyboard
keyboardController?.hide()
//To show keyboard
keyboardController?.show()

通过隐藏和显示请求,SoftwareKeyboardController我们可以控制键盘的可见性。

如果我们有带有键盘 ImeAction.Done 的 TextField,那么我们需要hide()在键盘操作的回调中调用 call。

b. LocalFocusManager

此外,我们可以通过从 TextField移除焦点来关闭键盘

val focusManager = LocalFocusManager.current
var text by remember {
    mutableStateOf("")
}

TextField(
    value = text,
    onValueChange = { text = it },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
    keyboardActions = KeyboardActions(
        onDone = { focusManager.clearFocus() }),
)

这将关闭键盘并从 TextField 中清除焦点,而SoftwareKeyboardController仅关闭键盘而不从任何 TextField 中移除焦点。

2. 出现键盘时如何调整布局

键盘在出现时会减少应用程序 UI 的可用空间。

当我们有太多的文本字段时,例如,我们有 5 到 6 个文本字段来输入用户详细信息的注册表单,可能并非所有字段都可见,一些文本字段可能会隐藏在键盘后面。那么如何预防呢?

a. windowSoftInputMode

使用该windowSoftInputMode属性,我们可以配置我们的键盘,它将如何影响我们的 UI 及其可见性状态。

在清单文件中设置adjustResizewindowSoftInputMode属性。

<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="adjustResize"
    .../>

系统会根据可用空间调整布局大小,以便在键盘出现在屏幕上时可以访问内容。

b. BringIntoViewRequester

通过BringIntoViewRequester我们可以自动滚动焦点更改以使 TextField 完全可见。BringIntoViewRequester是一个实验性 API,将来可能会改变。

这里的文本字段 9 不完全可见,BringIntoViewRequester自动滚动项目并带入父边界。让我们看看如何添加BringIntoViewRequester

val state = rememberLazyListState()
LazyColumn(
    state = state,
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally
){
    items(12) { item ->
        YourTextField(item)
        Spacer(modifier = Modifier.height(10.dp))
    }
}
//YourTextField
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun YourTextField(index: Int) {
  
    val bringIntoViewRequester = remember { BringIntoViewRequester() }
    val coroutineScope = rememberCoroutineScope()
    TextField(
       /* ... your text field value and onValueChange callback */   
      modifier = Modifier
            .bringIntoViewRequester(bringIntoViewRequester)
            .onFocusEvent { focusState ->
                if (focusState.isFocused) {
                    coroutineScope.launch {
                        bringIntoViewRequester.bringIntoView()
                    }
                }
            }
    )
}

Modifier.bringIntoViewRequester(bringIntoViewRequester)演示了可组合项如何要求其父级滚动,以便将使用此修饰符的组件带入其所有父级的边界。

BringIntoViewRequester 仅适用于windowSoftInputMode=”adjustResize”

c. imePadding

Ime 填充修饰符允许您将键盘填充应用于可组合。

在下面的示例中,我们在底部有一个按钮Column

Column(
    horizontalAlignment = Alignment.CenterHorizontally,
    modifier = Modifier
        .fillMaxSize()
        .padding(10.dp)
) {
    TextField(value = "", onValueChange = {})
    Spacer(Modifier.weight(1f))
    Button(onClick = {}) {
        Text(text = "Yeah Visible")
    }
}

不设置adjustResize属性windowSoftInputMode,按钮隐藏在键盘后面。

现在让我们设置imePadding在键盘出现时移动按钮。我们还需要设置WindowCompat.setDecorFitsSystemWindows(window, false)

Column(
    horizontalAlignment = Alignment.CenterHorizontally,
    modifier = Modifier
        .fillMaxSize()
        .statusBarsPadding()
        .navigationBarsPadding()
        .imePadding()
        .padding(10.dp)
) {
    TextField(value = "", onValueChange = {})
    Spacer(Modifier.weight(1f))
    Button(onClick = {}) {
        Text(text = "Yeah Visible")
    }
}

这是结果

3. Keyboard options

keyboardOptions在 TextField 中允许您配置键盘选项,例如自动大写、自动更正、您希望 TextField 和 IME 操作按钮使用的键盘类型。例如,对于密码 TextField,您既不想大写输入,也不想自动更正功能。

keyboardOptions = KeyboardOptions.Default.copy(
    capitalization = KeyboardCapitalization.None,
    autoCorrect = false,
    keyboardType = KeyboardType.Password,
    imeAction = ImeAction.Done
)

大写——自动将字符、单词或句子大写。
autoCorrect — 通知键盘是否启用自动更正。
keyboardType — 要在此文本字段中使用的键盘类型。例如,对于密码 TextField,键盘类型是KeyboardType.Password
imeAction — 应该在键盘上显示什么类型的操作按钮。

4. Keyboard actions

键盘动作用于检测键盘输入法动作按钮的点击事件。有 6 个键盘操作可用。

keyboardActions = KeyboardActions(
    onDone = { },
    onGo = { },
    onNext = { },
    onPrevious = { },
    onSearch = { },
    onSend = { },
)

例如,如果您想关注下一个文本字段,ImeAction.Next点击时,您将收到回调onNext

TextField(
    value = text,
    onValueChange = { text = it },
    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
    keyboardActions = KeyboardActions(
        onNext = { focusManager.moveFocus(FocusDirection.Down) }),
)

5.如何检测键盘

WindowInsets我们可以检查键盘是否存在于屏幕容器中。返回以像素为单位的底部空间。
WindowInsets.ime.getBottom(LocalDensity.current)

val isVisible = WindowInsets.ime.getBottom(LocalDensity.current) > 0
LaunchedEffect(key1 = isVisible) {
    if (isVisible) {
        //hide fab button
    } else {
        //show fab button
    }
}

而已。希望现在您对 Jetpack compose 中与键盘 API 的常见交互有基本的了解。随时在下面的评论部分添加您的宝贵反馈和建议。

谢谢你的支持!

如果喜欢你读到的东西,一定要在下面👏 👏👏 它——作为一个作家,它意味着世界