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);
}
public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
init();
}
758
感谢this SO answer,我推导出以下内容,在我的情况下,滚动浏览ViewPager的片段时效果很好...
private void hideKeyboard() {
// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
private void showKeyboard() {
// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
我觉得这个方法更好,更简单,更符合Android 's design pattern. In the simple example above (and usually in most of the common cases) you' ll有一个 EditText 有/有焦点,它通常也是首先调用键盘的那个(它肯定能在很多常见场景中调用它) ) . 以同样的方式, it 应该是释放键盘的那个,通常可以通过 ImeAction 完成 . 只要看看 EditText 与 android:imeOptions="actionDone" 的行为如何,您希望通过相同的方式实现相同的行为 .
@Override
public void onGlobalLayout() {
Configuration config = getResources().getConfiguration();
// Dont allow the default keyboard to show up
if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
}
}
private boolean isKeyboardVisible() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
mRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
return heightDiff > 100; // if more than 100 pixels, its probably a keyboard...
}
protected void showKeyboard() {
if (isKeyboardVisible())
return;
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (getCurrentFocus() == null) {
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
} else {
View view = getCurrentFocus();
inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
}
}
protected void hideKeyboard() {
if (!isKeyboardVisible())
return;
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
View view = getCurrentFocus();
if (view == null) {
if (inputMethodManager.isAcceptingText())
inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
} else {
if (view instanceof EditText)
((EditText) view).setText(((EditText) view).getText().toString()); // reset edit text bug on some keyboards bug
inputMethodManager.hideSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
30 回答
这应该工作:
以下是你在Mono for Android(AKA MonoDroid)中的表现
用这个
作为this all around solution的替代,如果你想关闭软键盘 from anywhere 而没有引用用于打开键盘的(EditText)字段,但是如果字段是聚焦的话仍然想要这样做,你可以使用它(来自活动):
如果要在单元或功能测试期间关闭软键盘,可以通过单击测试中的“后退按钮”来执行此操作:
我将"back button"放在引号中,因为上述内容不会触发
onBackPressed()
的相关活动 . 它只是关闭键盘 .确保在继续之前暂停一段时间,因为关闭后退按钮需要一点时间,因此后续点击视图等将在短暂停顿后暂停(1秒足够长时间) ) .
从搜索到这里,我找到了一个适合我的答案
Update: 我不知道为什么这个解决方案不再起作用(我刚刚在Android 23上测试过) . 请使用Saurabh Pareek的解决方案 . 这里是:
老答案:
简单易用的方法,只需调用 hideKeyboardFrom(YourActivity.this); 隐藏键盘即可
为了帮助澄清这种疯狂,我想首先代表所有Android用户道歉,谷歌对软键盘的彻头彻尾的荒谬处理 . 对于同样简单的问题,有这么多答案的原因有很多,因为这个API与Android中的许多其他API一样,设计非常糟糕 . 我可以想到没有礼貌的方式陈述它 .
我想隐藏键盘 . 我期望为Android提供以下声明:
Keyboard.hide()
. 结束 . 非常感谢你 . 但Android存在问题 . 您必须使用InputMethodManager
来隐藏键盘 . 好的,很好,这是Android的键盘API . 但!您需要拥有Context
才能访问IMM . 现在我们遇到了问题 . 我可能想要从没有任何用途或不需要任何Context
的静态或实用程序类中隐藏键盘 . 或者更糟糕的是,IMM要求您指定要隐藏键盘FROM的View
(或更糟糕的是,Window
) .这使得隐藏键盘变得如此具有挑战性 . 亲爱的谷歌:当我查找蛋糕的配方时,地球上没有
RecipeProvider
会拒绝向我提供配方,除非我先回答世界卫生组织,蛋糕将被吃掉,哪里会被吃掉!这个悲伤的故事以丑陋的事实告终:要隐藏Android键盘,您需要提供两种形式的识别:a
Context
和View
或Window
.我已经创建了一个静态实用程序方法,只要你从
Activity
调用它就可以非常稳定地完成工作 .请注意,此实用程序方法仅在从
Activity
调用时才有效!上面的方法调用目标Activity
的getCurrentFocus
来获取正确的窗口标记 .但是假设您想要隐藏_117256_中托管的
EditText
键盘?你不能使用上面的方法:这得胜't work because you'将传递对
Fragment
的主机Activity
的引用,当Fragment
显示时,它将没有集中控制!哇!因此,为了隐藏键盘中的碎片,我采用较低级别,更常见,更丑陋:以下是从更多时间浪费在追逐此解决方案中收集到的一些其他信息:
About windowSoftInputMode
还有另一个争论点需要注意 . 默认情况下,Android会自动将初始焦点分配给
Activity
中的第一个EditText
或可聚焦控件 . 由此可见,InputMethod(通常是软键盘)将通过显示自身来响应焦点事件 .AndroidManifest.xml
中的windowSoftInputMode
属性设置为stateAlwaysHidden
时,指示键盘忽略此自动分配的初始焦点 .几乎令人难以置信的是,当您触摸控件时,除了
focusable="false"
和/或focusableInTouchMode="false"
分配给控件之外,它似乎无法阻止键盘打开 . 显然,windowSoftInputMode设置仅适用于自动焦点事件,而不是聚焦触摸事件触发的事件 .因此,
stateAlwaysHidden
的名字确实非常糟糕 . 它也许应该被称为ignoreInitialFocus
.希望这可以帮助 .
UPDATE: More ways to get a window token
如果没有焦点视图(例如,如果您刚刚更改了片段,则会发生),还有其他视图将提供有用的窗口令牌 .
这些是上述代码的替代品
if (view == null) view = new View(activity);
这些没有明确提到您的活动 .在片段类中:
给定一个片段
fragment
作为参数:从您的内容正文开始:
UPDATE 2: Clear focus to avoid showing keyboard again if you open the app from the background
将此行添加到方法的末尾:
view.clearFocus();
在某些情况下,除其他所有方法外,此方法都可以使用这节省了我的一天:)
请在
onCreate()
中尝试以下代码Meier的解决方案也适用于我 . 在我的情况下,我的应用程序的顶级是tabHost,我想在切换标签时隐藏关键字 - 我从tabHost视图中获取窗口标记 .
以上答案适用于不同的场景但 If you want to hide the keyboard inside a view and struggling to get the right context try this:
并从构造函数获取上下文:)
感谢this SO answer,我推导出以下内容,在我的情况下,滚动浏览ViewPager的片段时效果很好...
只需在您的活动中使用此优化代码:
我几乎已经尝试了所有这些答案,我有一些随机问题,尤其是三星Galaxy s5 .
我最终得到的是强制展示和隐藏,它完美地运作:
如果这里的所有其他答案对您不起作用,那么还有另一种手动控制键盘的方法 .
使用它创建一个函数来管理
EditText
的一些属性:然后,确保
EditText
的onFocus打开/关闭键盘:现在,每当你想手动打开键盘时调用:
关闭电话:
我有这种情况,我的
EditText
也可以在AlertDialog
中找到,所以键盘应该在关闭时关闭 . 以下代码似乎在任何地方都可以使用:您可以使用InputMethodManager强制Android隐藏虚拟键盘,调用hideSoftInputFromWindow,传入包含焦点视图的窗口的标记 .
这将强制键盘在所有情况下都被隐藏 . 在某些情况下,您需要传入
InputMethodManager.HIDE_IMPLICIT_ONLY
作为第二个参数,以确保在用户未明确强制显示键盘时(仅通过按住菜单)隐藏键盘 .Note: 如果你想在Kotlin中这样做,请使用:
context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
答案简短
在
OnClick
监听器中使用IME_ACTION_DONE
调用EditText
的onEditorAction
深入研究
我觉得这个方法更好,更简单,更符合Android 's design pattern. In the simple example above (and usually in most of the common cases) you' ll有一个
EditText
有/有焦点,它通常也是首先调用键盘的那个(它肯定能在很多常见场景中调用它) ) . 以同样的方式, it 应该是释放键盘的那个,通常可以通过ImeAction
完成 . 只要看看EditText
与android:imeOptions="actionDone"
的行为如何,您希望通过相同的方式实现相同的行为 .检查一下related answer
我正在使用自定义键盘输入十六进制数字,因此我无法显示IMM键盘...
在v3.2.4_r1中添加了
setSoftInputShownOnFocus(boolean show)
以控制天气或不显示TextView获得焦点时的键盘,但它仍然隐藏,因此必须使用反射:对于旧版本,我使用
OnGlobalLayoutListener
获得了非常好的结果(但远非完美),在我的根视图中添加了ViewTreeObserver
,然后检查键盘是否显示如下:最后一个解决方案可以显示键盘一瞬间,并与选择手柄混淆 .
当键盘进入全屏时,不会调用onGlobalLayout . 为避免这种情况,请使用TextView#setImeOptions(int)或在TextView XML声明中:
Update: 刚刚找到了哪些对话框用于永不显示键盘并适用于所有版本:
我花了两天多的时间来处理帖子中发布的所有解决方案,并发现它们缺乏这种或那种方式 . 我的确切要求是有一个100%可靠性的按钮显示或隐藏屏幕键盘 . 当键盘处于隐藏状态时,无论用户点击什么输入字段,都不应重新出现 . 当它处于可见状态时,无论用户点击什么按钮,键盘都不会消失 . 这需要在Android 2.2上一直工作到最新的设备 .
您可以在我的应用clean RPN中看到此工作的实现 .
在许多不同的手机(包括froyo和姜饼设备)上测试了许多建议的答案后,很明显Android应用程序可以可靠地:
暂时隐藏键盘 . 当用户聚焦新文本字段时,它将再次重新出现 .
在活动开始时显示键盘,并在活动上设置一个标志,指示键盘应始终可见 . 只有在活动初始化时才能设置此标志 .
将活动标记为从不显示或允许使用键盘 . 只有在活动初始化时才能设置此标志 .
为了我,暂时隐藏键盘是不够的 . 在某些设备上,只要新文本字段被聚焦,它就会重新出现 . 由于我的应用程序在一个页面上使用多个文本字段,因此聚焦新文本字段将导致隐藏键盘再次弹回 .
不幸的是,列表中的第2项和第3项仅在启动活动时才具有可靠性 . 活动变得可见后,您无法永久隐藏或显示键盘 . 诀窍是当用户按下键盘切换按钮时实际重启您的活动 . 在我的应用程序中,当用户按下切换键盘按钮时,运行以下代码:
这会导致当前活动将其状态保存到Bundle中,然后启动活动,通过布尔值来指示是否应显示或隐藏键盘 .
在onCreate方法中,运行以下代码:
如果应该显示软键盘,则告诉InputMethodManager显示键盘,并指示窗口使软输入始终可见 . 如果应隐藏软键盘,则设置WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM .
这种方法可以在我测试过的所有设备上可靠运行 - 从运行Android 2.2的4岁HTC手机到运行4.2.2的nexus 7 . 这种方法的唯一缺点是你需要小心处理后退按钮 . 由于我的应用程序基本上只有一个屏幕(它是一个计算器),我可以覆盖onBackPressed()并返回到设备主屏幕 .
隐藏软键盘也很有用:
这可用于在用户实际触摸editText视图之前抑制软键盘 .
我还有一个隐藏键盘的解决方案:
这里
showFlag
的位置HIDE_IMPLICIT_ONLY
和0
的hiddenFlag
位置传递HIDE_IMPLICIT_ONLY
. 它会强行关闭软键盘 .对于我的情况,我在操作栏中使用了SearchView . 用户执行搜索后,键盘将再次弹出 .
使用InputMethodManager没有关闭键盘 . 我不得不clearFocus并将搜索视图的焦点设置为false:
到目前为止,Saurabh Pareek有最好的答案 .
不过,不妨使用正确的旗帜 .
实际使用的例子
这对我来说非常适合所有奇怪的键盘行为
在Manifest文件中添加到您的活动
android:windowSoftInputMode="stateHidden"
. 例: