InputMethodManager类

Android中软键盘的管理主要是通过InputMethodManager类来完成的。

InputMethodManager对象的获取方法如下:

获取到InputMethodManager对象后就可以通过调用其成员方法来对软键盘进行操作。不过在使用InputMethodManager对象前通常都需要判断其是否为null,避免运行时异常:

显示软键盘

Android中可以通过InputMethodManager的showSoftInput()方法来显示软键盘。

InputMethodManager的showSoftInput()方法原型为:

它有两个参数,第一个参数表示当前要接收软键盘输入的view,第二个参数是软键盘显示时的控制参数。使用InputMethodManager的showSoftInput()方法来显示软键盘有如下注意事项:

1.第一个参数中view必须是EditText,或者EditText的子类,如果是其他类型的View、如Button、TextView等,showSoftInput()方法不起作用。

2.第一个参数中的view必须是可以获取焦点的(即view.isFocusable()返回true),如果不能获取焦点,则showSoftInput()方法不起作用。EditText默认是可获取焦点的,所以此条件一般都可以满足。如果不满足,可以通过view.setFocusable(true);将其设置为可获取焦点的view。

3.第一个参数中的view当前必须已经获取到焦点(即view.isFocused()返回true),如果当前焦点不在该view上,则showSoftInput()方法不起作用。虽然EditText默认是可获取焦点的,但由于一个布局中可能会有多个控件可以获取焦点,焦点位置不一定会恰好在EditText上,所以此条件不一定满足。为了让showSoftInput()可以起作用,必须在之前showSoftInput()前先通过view.requestFocus()获取焦点。然后再执行showSoftInput()。

4.第一个参数中的view必须是可见的,即view.getVisibility()等于View.VISIBLE,如果view是不可见的,无论view.getVisibility()是View.INVISIBLE还是View.GONE,showSoftInput()方法都不起作用。如果view是不可见的,可以先通过view.setVisibility(View.VISIBLE)将其设置为可见。

5.当前布局必须已经完成加载,如果还未绘制完成,则showSoftInput()方法不起作用。特别的,在Activity的onCreate()中执行showSoftInput()是不起作用的。如果要再布局文件加载后就显示软键盘,可以通过postDelayed的方式来延迟执行showSoftInput()。延迟时间不能太短,一般要在50ms以上。代码示例如下:

6.InputMethodManager类中提供了另外一个显示软键盘的方法showSoftInputFromInputMethod,和showSoftInput不同的是,第一个参数传入的不是一个View对象,而是一个View对象的windowToken(对一个view对象可以通过getWindowToken()的方法获取到其windowToken。不过实际情况是,即使上述所有条件都满足,通过showSoftInput(view,flag)已经可以显示软键盘,但是通过showSoftInputFromInputMethod(view.getWindowToken(), flag)仍然无法显示软键盘。

7.参照Android官方文档,第二个参数提供一些额外的操作标记(additional operating flags),可以取0或者SHOW_IMPLICIT,0表示什么含义没有说明,SHOW_IMPLICIT表示本次显示软键盘的请求不是来自用户的直接请求,而是隐式的请求。且不说一会用数字,一会用常量名,光SHOW_IMPLICIT的说明恐怕除了这个接口的开发人员,没人能看懂这句话是什么意思。实际上这个参数还可以取第三个值SHOW_FORCED,直接在文档中被遗忘了。经过试验,这个参数的取值对软键盘的显示没有任何影响,无论取哪一个值软键盘都能够正常显示(即使随便输入一个整数,软键盘都可以显示)。实际上这个参数影响的并不是软键盘的显示,而是软键盘的隐藏。

隐藏软键盘

Android在InputMethodManager类中并没有提供一个和showSoftInput()对应的hideSoftInput()方法来隐藏软键盘,而是提供了一个showSoftInputFromInputMethod()相对应的hideSoftInputFromWindow()方法来隐藏软键盘。幸运的是,虽然showSoftInputFromInputMethod()不能正常显示软键盘,hideSoftInputFromWindow()倒是能够隐藏软键盘。

InputMethodManager的hideSoftInputFromWindow()方法原型为:

它同样有两个参数,第一个参数是一个View的windowToken,第二个参数是软键盘隐藏时的控制参数。使用 InputMethodManager的hideSoftInputFromWindow()方法来隐藏软键盘有如下注意事项:

1.第一个参数并不是指定一个View,而是一个View的windowToken。对一个view可以通过getWindowToken()的方法获取到其windowToken。

2.按照官方文档,第一个参数中的windowToken应当是之前请求显示软键盘的View的windowToken,也就是执行showSoftInput()时第一个参数中的View的windowToken。但是实际情况是,用任意一个当前布局中的已经加载的View的windowToken都可以隐藏软键盘,哪怕这个View被设置为INVISIBLE或GONE。因此,如果不知道之前是谁请求显示的软键盘,可以随便传入一个当前布局中存在的View的windowToken。特别的,可以传入一个Activity的顶层View的windowToken,即getWindow().getDecorView().getWindowToken(),来隐藏当前Activity中显示的软键盘,而不用管之前调用showSoftInput()的究竟是哪个View,示例代码如下:

这里还要注意的是,可以随便传入一个当前布局中存在的View的windowToken,并不代表可以传入任意一个View的windowToken,如下代码不能实现隐藏软键盘:

对新创建的view,必须将其加入到当前布局中后才可以用来隐藏软键盘。如下代码可以实现隐藏软键盘:

3.参照Android官方文档,第二个参数同样是提供了一些额外的操作标记(additional operating flags),可以取0或者HIDE_IMPLICIT_ONLY,0表示什么含义同样是没有说明,HIDE_IMPLICIT_ONLY表示当前的软键盘应当只在其不是被用户显式的显示的时候才隐藏(the soft input window should only be hidden if it was not explicitly shown by the user)。这句话虽然很拗口,但总算是有点有用的信息了。在显示软键盘时,可以使用的flag有0,SHOW_IMPLICIT和SHOW_FORCED,参照之前的描述,当显示软键盘指定flag为SHOW_IMPLICIT时表示隐式的显示,也就是这里非用户显式的显示,再参照这里的描述,如果隐藏软键盘时使用的flag为HIDE_IMPLICIT_ONLY,那么软键盘只有在非用户显式的显示的时候才隐藏,这意味着如果隐藏软键盘时使用的flag为HIDE_IMPLICIT_ONLY,那么只有当显示软键盘时指定的flag为SHOW_IMPLICIT时,软键盘才会隐藏,如果显示软键盘时指定的flag不是SHOW_IMPLICIT,而是0或者SHOW_FORCED,那么软键盘就不会隐藏。为了更完整的看出不同flag对隐藏软键盘的影响(再声明下,无论是显示软键盘时指定的flag,还是隐藏软键盘时指定的flag都只对隐藏软键盘有影响,对显示软键盘无影响), 分别在调用showSoftInput()时使用三个不同的标记,以及在调用hideSoftInputFromWindow()是使用三个不同的标记(隐藏软键盘时同样还有一个HIDE_NOT_ALWAYS标记,它同样在文档中被遗忘了),对是否能够隐藏软键盘进行测试,测试结果如下:

(T表示可以隐藏,F表示不能隐藏)

可以看到,在隐藏软键盘时使用HIDE_IMPLICIT_ONLY标记,确实只有在显示软键盘时使用SHOW_IMPLICIT时才会隐藏。此外,当隐藏软键盘时使用0作为标记,无论showSoftInput()时使用的是哪个参数,都可以隐藏软键盘。

切换软键盘状态

在InputMethodManager类中还提供了一个toggleSoftInput()的方法来在显示和隐藏软键盘之间切换,也就是说,如果当前软键盘是隐藏的,那么执行toggleSoftInput()方法时会显示软键盘,如果当前软键盘是显示的,那么执行toggleSoftInput()方法时会隐藏软键盘。

InputMethodManager的toggleSoftInput()方法原型为:

它同样有两个参数,第一个参数是显示软键盘时使用的标记,第二个参数是隐藏软键盘时使用的标记。使用InputMethodManager的toggleSoftInput()方法来切换软键盘显示状态有如下注意事项:

1.showFlags为显示软键盘时使用的标记,只有当前软键盘处于隐藏状态时才会使用。hideFlags是隐藏软键盘时使用的标记,只有当前软键盘处于显示状态时才会使用。

2.showFlags和hideFlags取值范围,以及不同取值的影响和上文分析的一样。即showFlags和hideFlags都只影响软键盘的隐藏,不影响软键盘的显示。不同取值对软键盘隐藏的影响参见上文中的表格。

3.和showSoftInput()方法不同的是,使用toggleSoftInput()显示软键盘时,并不要求当前界面布局中有一个已经获取焦点的EditText,即使当前布局是完全空白的,一个View也没有(除了最外层的Layout),toggleSoftInput()也能够显示软键盘。不过如果没有一个已经获取焦点的EditText,那么软键盘中的按键输入都是无效的。就像这样。

4.显示软键盘时,要求当前布局必须已经加载完成,如果还未绘制完成,则toggleSoftInput()方法不起作用。这点和之前调用showSoftInput()显示软键盘时描述的第5点要求是一样的。特别的,在Activity的onCreate()中执行toggleSoftInput()必须通过postDelayed的方式来延迟执行。延迟时间一般要在50ms以上。

5.当隐藏软键盘时,不需要知道之前触发软键盘显示的View是哪一个或获取当前布局中任何一个View的windowToken,只要hideFlags能够隐藏就可以。由于hideFlags为0时总是能够隐藏的,因此,使用toggleSoftInput(0, 0)应当是最方便的无条件隐藏软键盘的方法,前提是知道当前软键盘确实是处于显示状态。不过遗憾的是Android没有任何API可以直接获取到软键盘的状态是显示还是隐藏的。

部分源码解读

显示和隐藏软键盘的源码大都在InputMethodManagerService.java文件里。这个文件有3000多行代码,还有很多是其他类的交互,我也没有仔细研究,这里只是将其在一些片段贴出来,做一个大概的分析:

1.showSoftInput

showSoftInput()会进入到showCurrentInputLocked()方法中,这里有这样一段:

可以看到这里只是将showSoftInput的第二个参数flag和SHOW_IMPLICIT,SHOW_FORCED相与,根据结果对mShowExplicitlyRequested和mShowForced赋值。在showCurrentInputLocked()方法没有其他用到flags的地方,也没有用到mShowExplicitlyRequested和mShowForced。这就解释了,执行showSoftInput()时传入任意的flags都不会影响软键盘的显示。

2.hideSoftInputFromWindow

hideSoftInputFromWindow会进入hideCurrentInputLocked()方法,在hideCurrentInputLocked()方法的开头有这样一段:

这里的判断用到了隐藏软键盘时使用的flags,以及mShowExplicitlyRequested和mShowForced的值,如果不满足条件就直接返回了。可以看到当flags为HIDE_IMPLICIT_ONLY时,如果mShowExplicitlyRequested和mShowForced任意一个为true,都会返回false。当flags为HIDE_NOT_ALWAYS时,如果mShowForced为true,也会返回false,当flags为0时,两个if条件都不满足。这就解释了显示软键盘时使用的flags影响的是后面隐藏软键盘是否成功,以及隐藏软键盘时使用0作为flags总是能够隐藏软键盘

结论

显示软键盘最可靠的方法如下:

view必须是VISIBLE的EditText,如果不是VISIBLE的,需要先将其设置为VISIBLE。

当前界面必须已经加载完成,不能直接在Activity的onCreate(),onResume(),onAttachedToWindow()中使用,可以在这些方法中通过postDelayed的方式来延迟执行showSoftInput()

隐藏软键盘最方便的方法如下:

view可以当前布局中已经存在的任何一个View,如果找不到可以用getWindow().getDecorView()

android隐藏软键盘方法,Android显示和隐藏软键盘方法相关推荐

  1. Android监听系统输入法键盘弹出显示与隐藏事件

    Android监听系统输入法键盘弹出显示与隐藏事件 有时候需要监听Android系统输入法的弹出显示事件,比如:微信聊天时,不管你当前在聊天中的什么位置(上滑查看消息历史),每当你点击输入框时,都会自 ...

  2. Android之按钮点击事件——显示图片隐藏图片

    哈喽!时隔两个月,我又和大家见面啦! 今天,我要分享的内容一如既往的很基础,即关于Android的按钮点击事件--显示图片&&隐藏图片,它的执行过程比较简单,所以这里我就不放什么图片或 ...

  3. html图片的隐藏与显示,Jquery中使用show()与hide()方法动画显示和隐藏图片

    (1)功能描述 在页面中单击"显示"连接,通过show()方法以动画的方式显示一幅图片,同时在方法中执行一个回调函数,用于改变图片的边框样式:单击已显示的图片时,通过hide()以 ...

  4. Android适配华为手机虚拟按键显示或隐藏

    华为的一些手机的屏幕上的虚拟按键是可以显示或者隐藏的,因此在布局适配的时候就要考虑到这个问题,要不然当虚拟按键被隐藏后界面的布局就会出现问题,下面给出一种解决方法,(原文来自:安卓适配碰到的一些问题) ...

  5. FineReport(帆软)根据条件显示和隐藏列数据

    情景:刚刚接到一个需求,省.市.区县三级联动下拉选项,要求选择省的时候,数据展示不作处理:选择市的时候,需要展示省的数据:选择区县的时候,需要展示省.市两列数据. 那么,这个设定,该如何通过帆软这款软 ...

  6. 显示隐藏图片html,JavaScript实现显示和隐藏图片

    JavaScript之显示和隐藏图片,供大家参考,具体内容如下 点击按钮可以显示和隐藏图片(默认显示),附上代码: 显示和隐藏图片 隐藏 // 1.获取事件源 var obtn = document. ...

  7. html显示隐藏图片,简单的图片显示与隐藏

    今天有个小问题,在iPhone上显示所有图片.但是不可能一次显示全部,只能显示图片的名称列表.需要点击图片名,然后显示图片,再次点击的话,就隐藏图片.一个比较简单的javascript代码,在这里记录 ...

  8. android笔记之在WebView中显示ProgressBar的两种方法

    http://blog.csdn.net/liuzhidong123/article/details/6450334 本文基于Creative Commons Attribution 2.5 Chin ...

  9. display 隐藏css,CSS-元素的显示与隐藏

    display display:none隐藏元素,不是删除,但元素一直存在于页面中 特点:隐藏之后不再保留位置 visibility visible 对象可见 hidden 对象隐藏 特点:隐藏之后继 ...

  10. android监控虚拟键盘,android虚拟键盘的监控,显示和隐藏

    android虚拟键盘的监控,显示和隐藏 听到一个键盘监控[显示.隐藏]的问题,上网找了下解决方案. 有提到使用onSizeChange方法监控的,也有监控onLayout方法的. 思路:在弹出键盘时 ...

最新文章

  1. 实时获取vuex更新的新数据_三网运营商大数据实时截流,网站手机号获取
  2. android拍照自动裁剪_新功能上线!智能人像抠图、图片自由裁剪,PPT 还能这么玩?...
  3. 多云战略未来五大趋势分析,必看!
  4. 福禄克2500V数字绝缘电阻测试仪开箱与上手实测
  5. 离散制造业的数据采集之路
  6. 移动端下网页border:1px显示
  7. matlab学习-线性规划
  8. jumpserver 使用教程_Jumpserver之快速入门
  9. linux fb设备驱动,linux设备驱动归纳总结(八):1.总线、设备和驱动
  10. 伯克利区块链课程:替代密码验证,比特币应用数字签名的进化之路
  11. Android Studio内置JDK源码关联和断点错乱问题解决
  12. 2009程序员考试大纲
  13. zedgraph显示最小刻度_关于ZedGraph几个难点
  14. Java 各种单例模式实现代码
  15. Can‘t Update No tracked branch configured for branch
  16. ImportError: cannot import name 'imsave' from 'scipy.misc' (C:\Users\DELL\AppData\Roaming\Python\Pyt
  17. 管理“项目”之人际关系篇
  18. java中eof错误是啥意思_EOFException异常详解
  19. (程序详解)51单片机+DS12C887+1602高精度时钟,软件:keil4,Proteus 8
  20. iPad pro能运行c语言吗,办公实战 iPad Pro还是洗洗睡吧_平板电脑评测-中关村在线...

热门文章

  1. 鱼群被捕食matlab,鱼群运动行为模型_毕业论文.doc
  2. JS实现 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
  3. 阿里P8推荐的10本Java实战书籍,Java开发进阶必备书单
  4. agile approach
  5. 如何连接公司或家中电脑实现远程桌面
  6. Jenkins 第一次任务构建时提示:ERROR: Timeout after 10 minutes
  7. 如何在ex表格导入php_phpexcel导入excel数据使用方法实例
  8. 搭建离岸架构,对财富进行管理
  9. 电脑风扇声音大怎么办
  10. 二叉树的遍历-树-数据结构和算法(Java)