我正在 POS 应用程序中制作搜索屏幕,并希望在存在 TextField 时始终显示软件键盘。理想情况下,我想拦截用户隐藏键盘的事件,以将我的搜索小部件与键盘一起隐藏。
目前我有
@Composable
fun Search(onHide: () -> Unit) {
var query by rememberSaveable { mutableStateOf("") }
BackHandler {
onHide() //works only when keyboard is already hidden
}
Column(modifier = Modifier.fillMaxHeight()) {
TextField(value = query, onValueChange = { query = it },
modifier = Modifier.focusRequester(focusRequester))
myItemsList.filter { it.title.startsWith(query) }.take(7).forEach {
SearchLine(it)
}
}
LaunchedEffect(key1 = focusRequester) {
focusRequester.requestFocus()
focusRequester.captureFocus()
// keyboardController.show() //it is shown due to focus anyway
}
}
对于上下文,我这样使用它:
fun Content() {
var searchMode by rememberSaveable { mutableStateOf(true) } //FIXME false
AppTheme {
Surface {
if (searchMode) {
Search(onHide = { searchMode = false })
} else {
/* normally available activtiy contents */
}
}
}
}
额外问题:
这些可能是相关的,因为如果这也不可能,那么我最好的选择是使用自定义应用程序内键盘吗?我不想,因为一些棘手的语言环境,比如日语。
BackHandler { <breakpoint> }
。当用户尝试隐藏键盘时,它根本不会被触发。focusRequester.captureFocus()
的文本字段修饰符。我不知道它是否有助于捕获焦点,我的 TextField 是唯一存在的可聚焦事物,并且始终聚焦,但它并不能阻止用户隐藏键盘。TextInputService.startInput()
,有onEditCommand和onImeActionPerformed字段,当用户隐藏键盘时它们也不会被触发KeyboardActions(onAny = { <breakpoint> })
,隐藏不会触发它。android:windowSoftInputMode="stateAlwaysVisible"
。它什么也没做。LaunchedEffect(key1 = focusRequester) { keyboardController.show() }
显示键盘,但仍可隐藏。imm!!.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
带有 activtiy 的窗口令牌,什么也没做,根据我的理解,它与 Compose 无关。也许更多,我已经累坏了:(
“隐藏键盘”键码是17179869184(根据this),因此您可以通过拦截按键来防止隐藏键盘操作。 图片
TextField(
value = value,
onValueChange = { value = it },
modifier = Modifier
.onPreInterceptKeyBeforeSoftKeyboard {
if (it.key.keyCode == 17179869184 && isFocused) {
true
} else {
false
}
}
.onFocusChanged {
isFocused = it.isFocused
setSoftKeyboardVisibility(isFocused)
}
)
不幸的是,有些情况该解决方案无法涵盖。当手势导航栏功能打开时,通过向后滑动手势隐藏键盘。 图片(滑动手势)
可能还有其他方法来隐藏键盘,不仅是针对每个设备,还针对软件键盘。 因此,我认为实现自定义应用内键盘是确保键盘可见性的最佳方法。