我的布局中有一个EditText
和一个Button
。
在编辑字段中写入并单击 后Button
,我想在触摸键盘外部时隐藏虚拟键盘。我认为这是一段简单的代码,但我在哪里可以找到它的示例?
为了澄清这种疯狂,我首先代表所有 Android 用户为 Google 对软键盘的荒谬处理道歉。对于同一个简单的问题,有这么多不同的答案的原因是,这个 API 与 Android 中的许多其他 API 一样,设计得非常糟糕。我想不出礼貌的方式来表达它。
我想隐藏键盘。我希望为 Android 提供以下声明:Keyboard.hide()
. 结束。非常感谢你。但是安卓有问题。您必须使用InputMethodManager
来隐藏键盘。好的,好的,这是 Android 的键盘 API。但!您必须拥有Context
才能访问 IMM。现在我们有一个问题。我可能想对没有用或不需要任何Context
. 或者更糟糕的是,IMM 要求您指定要隐藏键盘的内容View
(或更糟的是,是什么Window
)。
这就是隐藏键盘如此具有挑战性的原因。亲爱的谷歌:当我查找蛋糕的食谱时,RecipeProvider
地球上没有人会拒绝向我提供食谱,除非我先回答谁会吃蛋糕以及在哪里吃蛋糕!!
这个悲伤的故事以一个丑陋的事实结束:要隐藏 Android 键盘,您将需要提供 2 种身份识别形式:aContext
和 aView
或 a Window
。
我创建了一个静态实用程序方法,它可以非常可靠地完成这项工作,前提是您从Activity
.
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
请注意,此实用程序方法仅在从Activity
! getCurrentFocus
目标的上述方法调用Activity
以获取正确的窗口令牌。
但是假设您想对EditText
托管在DialogFragment
? 您不能为此使用上述方法:
hideKeyboard(getActivity()); //won't work
这将不起作用,因为您将传递对Fragment
's host的引用,在Activity
显示时将没有焦点控制Fragment
!哇!因此,为了将键盘从片段中隐藏起来,我求助于较低级别、更常见和更丑陋的方法:
public static void hideKeyboardFrom(Context context, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
以下是从追逐此解决方案所浪费的更多时间中收集的一些附加信息:
关于 windowSoftInputMode
还有一个争论点需要注意。默认情况下,Android将自动最初的焦点分配给第一个EditText
在你或可聚焦控制Activity
。很自然地,InputMethod(通常是软键盘)将通过显示自己来响应焦点事件。中的windowSoftInputMode
属性AndroidManifest.xml
设置为 时stateAlwaysHidden
,指示键盘忽略此自动分配的初始焦点。
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
几乎令人难以置信的是,当您触摸控件时,它似乎没有阻止键盘打开(除非focusable="false"
和/或focusableInTouchMode="false"
分配给控件)。显然,windowSoftInputMode 设置仅适用于自动焦点事件,不适用于触摸事件触发的焦点事件。
因此,stateAlwaysHidden
确实是非常糟糕的名字。也许应该ignoreInitialFocus
改为调用它。
更新:获取窗口令牌的更多方法
如果没有聚焦视图(例如,如果您刚刚更改片段可能会发生这种情况),还有其他视图将提供有用的窗口标记。
这些是上述代码的替代方案,if (view == null) view = new View(activity);
这些并未明确指代您的活动。
在片段类中:
view = getView().getRootView().getWindowToken();
给定一个片段fragment
作为参数:
view = fragment.getView().getRootView().getWindowToken();
从您的内容正文开始:
view = findViewById(android.R.id.content).getRootView().getWindowToken();
更新 2:如果您从后台打开应用程序,请清除焦点以避免再次显示键盘
将此行添加到方法的末尾:
view.clearFocus();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句