关闭 / 隐藏 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调用时才有效!这个方法调用了目标ActivitygetCurrentFocus从而获取适当的窗口 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还不错。

希望能有所帮助。

更多相关文章

  1. Android中View的滑动
  2. Service和Activity通讯的3种常用方式示例
  3. 【Android】高效ListView
  4. Android(安卓)架构组件(一)——Lifecycle
  5. Android(安卓)调用系统相机拍照保存以及调用系统相册的方法
  6. 学习Android(安卓)--从现在开始
  7. Android(安卓)studio gradle build 太慢,有时会卡住的解决方法
  8. Android(安卓)TextView文字横向自动滚动(跑马灯)
  9. Android(安卓)TV Input Framework(TIF)--显示Tv Input

随机推荐

  1. 作为Android开发者 你真的知道Android按
  2. Android实现pppoe拨号上网(二)具体步骤
  3. 百度强势介入分裂 Android
  4. Android核心分析28篇,强烈推荐android初学
  5. Android(安卓)终于要跟 Chromium 和 WebK
  6. 腾讯T3大牛带你了解 2019 Android开发趋
  7. 基于Android的校园跳蚤市场(二手)的设计与
  8. Android学习及如何利用android来赚钱
  9. Android(安卓)5.1 Settings模块源码分析
  10. 你的Android不好用,都是因为这几点原因