我的布局中有一个 EditText
和一个 Button
。
在编辑字段中写入并单击 Button
后,我想在键盘外触摸时隐藏虚拟键盘。我假设这是一段简单的代码,但我在哪里可以找到它的示例?
原文由 Vidar Vestnes 发布,翻译遵循 CC BY-SA 4.0 许可协议
我的布局中有一个 EditText
和一个 Button
。
在编辑字段中写入并单击 Button
后,我想在键盘外触摸时隐藏虚拟键盘。我假设这是一段简单的代码,但我在哪里可以找到它的示例?
原文由 Vidar Vestnes 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以使用下面的扩展来隐藏和显示软键盘
fun Fragment.showKeyboard(view: View) {
view.isFocusableInTouchMode = true
view.requestFocus()
val imm = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE)
as InputMethodManager
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) }
fun Fragment.hideKeyboard(view: View) {
view.clearFocus()
val imm = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE)
as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0) }
要呼叫分机,您只需在片段中遵循以下步骤
showKeyboard(Your edittext ID)
hideKeboard(Your edittext ID)
原文由 Morteza Allahyari 发布,翻译遵循 CC BY-SA 4.0 许可协议
2 回答1.3k 阅读✓ 已解决
2 回答2.6k 阅读
2 回答1.7k 阅读
1 回答2.1k 阅读
1 回答1.1k 阅读
1 回答1.3k 阅读
1.3k 阅读
为了帮助澄清这种疯狂,我想首先代表所有安卓用户为谷歌对软键盘的荒谬处理表示歉意。对于同一个简单的问题,有这么多答案,每一个都不同,原因是这个 API 和 Android 中的许多其他 API 一样,设计得很糟糕。我想不出有礼貌的说法。
我想隐藏键盘。我希望为 Android 提供以下声明:
Keyboard.hide()
。结束。非常感谢。但是安卓有问题。您必须使用InputMethodManager
来隐藏键盘。好的,好的,这是 Android 的键盘 API。但!您需要拥有Context
才能访问 IMM。现在我们有一个问题。我可能想从一个静态或实用程序类中隐藏键盘,这些类没有使用或不需要任何Context
。或者更糟糕的是,IMM 要求您指定要隐藏键盘的View
(或者更糟糕的是Window
)。这就是隐藏键盘如此具有挑战性的原因。亲爱的谷歌:当我查找蛋糕的食谱时,地球上没有
RecipeProvider
会拒绝向我提供食谱,除非我先回答谁会吃蛋糕以及在哪里吃蛋糕会被吃掉!!这个悲伤的故事以丑陋的事实结束:要隐藏 Android 键盘,您将需要提供 2 种形式的标识:
Context
和View
或Window
.我创建了一个静态实用程序方法,只要您从
Activity
调用它,它就可以非常可靠地完成这项工作。请注意,此实用程序方法仅在从
Activity
调用时才有效!上述方法调用目标getCurrentFocus
的Activity
来获取正确的窗口令牌。但是假设您想隐藏
EditText
托管在DialogFragment
中的键盘?您不能为此使用上述方法:这不起作用,因为您将传递对
Fragment
的主机Activity
的引用,当显示Fragment
时,它将没有集中控制!哇!因此,为了将键盘从碎片中隐藏起来,我采用了更底层、更常见、更丑陋的方法:以下是从浪费更多时间追逐此解决方案中收集的一些附加信息:
关于windowSoftInputMode
还有一个争论点需要注意。默认情况下,Android 会自动将初始焦点分配给第一个
EditText
或您的Activity
中的可聚焦控件。很自然地,InputMethod(通常是软键盘)将通过显示自己来响应焦点事件。 — 中的windowSoftInputMode
属性设置为stateAlwaysHidden
AndroidManifest.xml
,指示键盘忽略此自动分配的初始焦点。几乎令人难以置信的是,当您触摸控件时,它似乎无法阻止键盘打开(除非将
focusable="false"
和/或focusableInTouchMode="false"
分配给控件)。显然,windowSoftInputMode 设置仅适用于自动焦点事件,不适用于由触摸事件触发的焦点事件。因此,
stateAlwaysHidden
的名字确实很糟糕。或许应该改为ignoreInitialFocus
。更新:获取窗口令牌的更多方法
如果没有焦点视图(例如,如果您只是更改片段可能会发生),则有其他视图将提供有用的窗口标记。
这些是上述代码的替代品
if (view == null) view = new View(activity);
这些并不明确涉及您的活动。在片段类中:
给定一个片段
fragment
作为参数:从您的内容正文开始:
更新 2:如果您从后台打开应用程序,请清除焦点以避免再次显示键盘
将此行添加到方法的末尾:
view.clearFocus();