如何从 Jetpack Compose TextField 关闭虚拟键盘?
Posted
技术标签:
【中文标题】如何从 Jetpack Compose TextField 关闭虚拟键盘?【英文标题】:How to close the virtual keyboard from a Jetpack Compose TextField? 【发布时间】:2020-03-26 17:20:18 【问题描述】:我正在使用 Jetpack Compose TextField
,我想在用户按下操作按钮(imeActionPerformed
参数)时关闭虚拟键盘。
val text = +state ""
TextField(
value = text.value,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done,
onImeActionPerformed =
// TODO Close the virtual keyboard here <<<
onValueChange = s -> text.value = s
)
【问题讨论】:
【参考方案1】:在 alpha-12 发布后编辑: 请参阅 @azizbekian 的回复。
pre-alpha-12 响应
我找到了解决方案here :)
fun hideKeyboard(activity: Activity)
val imm: InputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
var view = activity.currentFocus
if (view == null)
view = View(activity)
imm.hideSoftInputFromWindow(view.windowToken, 0)
我只需要从我的组件中调用上面的函数:
// getting the context
val context = +ambient(ContextAmbient)
// textfield state
val text = +state ""
TextField(
value = text.value,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done,
onImeActionPerformed =
if (imeAction == ImeAction.Done)
hideKeyboard(context as Activity)
onValueChange = s -> text.value = s
)
【讨论】:
【参考方案2】:通过1.0.x
可以使用LocalSoftwareKeyboardController
类来控制当前的软键盘,然后使用hide
方法:
var text by remember mutableStateOf(TextFieldValue("Text"))
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
value = text,
onValueChange =
text = it
,
label = Text("Label") ,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = keyboardController?.hide())
)
此解决方案会关闭键盘而不从当前TextField
移除焦点。
只是为了突出区别:
val focusManager = LocalFocusManager.current
focusManager.clearFocus()
此代码关闭键盘,从 TextField 移除焦点。
【讨论】:
这是每个 android 开发者的梦想 这与 focusManager 方法 (***.com/a/66259111/2911458) 有什么区别?我们应该什么时候使用它们? @stkent 这个解决方案只隐藏键盘。另一种解决方案也从当前的 TextField 中移除焦点(光标仍在显示,它可能仍被突出显示等) 在两种解决方案之间进行选择时,请同时注意 ux-continuity:默认行为:向后滑动一次隐藏键盘,第二次滑动清除焦点。 @stkent 了解更多详情,请参阅下面***.com/a/68650009/12871582的回答【参考方案3】:从 compose 1.0.0-alpha12
开始(在 compose 1.0.5
中仍然有效)onImeActionPerformed
已被弃用,建议的方法是使用 keyboardActions
和 keyboardOptions
的组合:
val focusManager = LocalFocusManager.current
OutlinedTextField(
value = ...,
onValueChange = ...,
label = ...,
keyboardActions = KeyboardActions(onDone = focusManager.clearFocus() ),
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done, keyboardType = KeyboardType.Password),
)
focusManager.clearFocus()
将负责关闭软键盘。
【讨论】:
【参考方案4】:在点击按钮时隐藏键盘
要添加Gabriele Mariotti's solution,如果你想有条件地隐藏键盘,比如点击按钮后,使用这个:
keyboardController?.hide()
例如,点击添加按钮后隐藏键盘:
var newWord by remember mutableStateOf("")
val keyboardController = LocalSoftwareKeyboardController.current
// Setup the text field with keyboard as provided by Gabriele Mariotti
...
Button(
modifier = Modifier
.height(56.dp),
onClick =
if (!newWord.trim().isNullOrEmpty())
wordViewModel.onAddWord(newWord.trim())
newWord = ""
keyboardController?.hide()
...
【讨论】:
【参考方案5】:在1.0.0
中,您可以使用SoftwareKeyboardController
或FocusManager
来执行此操作。
此答案侧重于它们的差异。
设置:
var text by remember mutableStateOf("")
TextField(
value = text,
onValueChange = text = it ,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = /* TODO */ ),
)
软件键盘控制器:
基于@Gabriele Mariottis
的回答。
val keyboardController = LocalSoftwareKeyboardController.current
// TODO =
keyboardController?.hide()
这只会关闭键盘,但不会从任何聚焦的 TextField 中清除焦点(注意光标和粗下划线)。
焦点管理器:
基于@azizbekians
的回答。
val focusManager = LocalFocusManager.current
// TODO =
focusManager.clearFocus()
这会关闭键盘并从 TextField 中清除焦点。
【讨论】:
【参考方案6】:实现'androidx.compose.material3:material3:1.0.0-alpha02'
Ime 操作中带有隐藏键盘的文本字段
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun TextFieldWithHideKeyboardOnImeAction()
val keyboardController = LocalSoftwareKeyboardController.current
var text by rememberSaveable mutableStateOf("")
TextField(
value = text,
onValueChange = text = it ,
label = Text("Label") ,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone =
keyboardController?.hide()
// do something here
)
)
【讨论】:
以上是关于如何从 Jetpack Compose TextField 关闭虚拟键盘?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Jetpack compose 中的 drawable 加载图像?