关闭 / 隐藏 Android(安卓)软键盘
关闭 / 隐藏 Android 软键盘
问题链接
我在布局上放了一个EditText
和一个Button
。在文本框里输入内容并且点击Button
之后,我想把虚拟键盘隐藏起来。我觉得会有一些简单的,一行或者两行的方法来实现这个效果。我该在哪找到这样的例子呢?
Reto Meier 的答案
你可以使用InputMethodManager
强制让 Android 隐藏虚拟键盘。调用hideSoftInputFromWindow
,把包含文本框的窗口标记(token)传递进去。
EditText myEditText = (EditText) findViewById(R.id.myEditText);// Check if no view has focus:View view = this.getCurrentFocus();if (view != null) { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0);}
这会在任何情况下都强制隐藏键盘。一些时候你可能会想在第二个参数使用InputMethodManager.HIDE_IMPLICIT_ONLY
来确保仅仅在用户没有显式调用键盘(按下菜单)时隐藏。
Garnet Ulrich 的答案
另一种隐藏软键盘的方法是:
getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
这个方法可以在用户触摸EditText
之前让软键盘始终保持隐藏。
rmirabelle 的答案
为了弄清楚这种疯狂的行为,作为开篇,我要代表所有 Android 用户为 Google 对软键盘完全荒唐的对待方式而道歉。同一个简单的问题有如此多种各不相同的答案,其原因和 Android 的其他许多方面一样,是糟糕的 API 设计。对此我想不出任何礼貌的方式来陈述。
我想把键盘隐藏掉,而我希望通过这样的语句来实现:Keyboard.hide()
。就这一句,谢谢。但是 Android 有问题,你必须用InputMethodManager
来隐藏键盘。好的,可以,这就是 Android 操作键盘的 API。但是!它要求你必须拥有一个Context
才能访问到 IMM,现在问题来了,我可能想在一个静态或者工具类里隐藏键盘,但是没有办法也没有需要访问任何的Context
。或者(也更糟),IMM 需要你指定从哪一个View
(或者更糟,从哪一个Window
)隐藏键盘。
这就是让隐藏键盘变得如此困难的原因。亲爱的 Google,当我查阅蛋糕的做法时,根本不会有一个让我除非先回答谁会吃蛋糕、在什么地方吃蛋糕,否则就不告诉我蛋糕做法的RecipeProvider
!
这个悲伤的故事将会以一个丑陋的事实结束:要隐藏键盘,你需要提供两种鉴定方式——一个是Context
,另一个要么是View
,要么是Window
。
我写了一个静态工具方法,从而能可靠地完成这个操作,只需要提供一个Activity
:
public static void hide_keyboard(Activity activity) { InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); // 找到当前获得焦点的 view,从而可以获得正确的窗口 token View view = activity.getCurrentFocus(); // 如果没有获得焦点的 view,创建一个新的,从而得到一个窗口的 token if(view == null) { view = new View(activity); } inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);}
要注意,这个方法只有从一个Activity
调用时才有效!这个方法调用了目标Activity
的getCurrentFocus
从而获取适当的窗口 token。
但如果你想从一个DialogFragment
中的EditText
来隐藏键盘呢?你不能像这样调用上面的方法:
hide_keyboard(get_activity()); // 没用
这样不会达到效果,因为你传递的是Fragment
的宿主Activity
的引用,而在显示Fragment
的时候,这个Activity
是没有获得焦点的控件的!因此,要从Fragment
隐藏键盘,需要用到更加低级的、更加普遍也更丑陋的方法:
public static void hide_keyboard_from(Context context, View view) { InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);}
以下是为了解决这个问题而四处搜集到的一些额外信息:
关于windowSoftInputMode
还有另一种需要注意的观点。默认情况下,Android 会自动为Activity
的第一个EditText
或者其他可获取焦点的控件赋予初始焦点,输入法(通常也就是软键盘)也自然会响应这个事件,自动出现。AndroidManifest.xml
中的windowSoftInputMode
属性如果设置为stateAlwaysHidden
,键盘就会忽略这个自动分配初始焦点的事件。
<activity android:name=".MyActivity" android:windowSoftInputMode="stateAlwaysHidden"/>
几乎无法相信的是,上面的代码对于触摸控件居然毫无作用,键盘仍然会打开(除非为控件设置focusable="false"
并且/或者focusableInTouchMode="false"
)。很明显,windowSoftInputMode
只对自动获得焦点事件有作用,而对触摸触发的焦点事件没有影响。
因此,stateAlwaysHidden
这个名字取得太烂了。或许叫做ignoreInitialFocus
还不错。
希望能有所帮助。
更多相关文章
- Android中View的滑动
- Service和Activity通讯的3种常用方式示例
- 【Android】高效ListView
- Android(安卓)架构组件(一)——Lifecycle
- Android(安卓)调用系统相机拍照保存以及调用系统相册的方法
- 学习Android(安卓)--从现在开始
- Android(安卓)studio gradle build 太慢,有时会卡住的解决方法
- Android(安卓)TextView文字横向自动滚动(跑马灯)
- Android(安卓)TV Input Framework(TIF)--显示Tv Input