Android软键盘的状态获取

被软键盘挡住的话可以试试先在布局上套个scroll view,如果这样做不行,想获得软键盘的状态,我有两种方法,是在我解一个bug中集同事之力想出来的。
法一:在InputMethodManager中增加一个方法来获得软键盘的状态。我是通过类比showSoftInput()这个方法找到该怎么加aidl的,整个调用流程是这样的:
       1)客户应用程序获取系统服务,得到一个InputMethodManager实例。
       2)调用我们加到imm中获得键盘状态的方法。imm中有两套接口,一套InputMethod.aidl,一套是InputMethodSession.aidl。我使用的是前一个,后一个没试过。
       3)这个方法会调用imm内部实例InputMethodManagerService的方法,这个service才是真正跟InputMethodService通信的服务。
       4)imms不会直接调用InputMethodService,也就是当前的输入法,而是调用一个叫InputMethodwrapper类。
       5)imw再调用当前输入法服务,这些输入法都是继承自InputMethodService的。
所以真正操作起来,这些涉及到的类如果继承自aidl的话都需要在相应的aidl中增加接口。还有一点要注意的是返回值的传递。因为是在不同进程中,在服务器端返回boolean值是没啥用的,可以参考showSoftInput这个方法的做法,用个ResultReceiver。
       路是打通了,可是InputMethodService里有那么多的boolean成员变量,到底用哪些呢?可以看到ims中有个IsInputViewShown()方法,一开始我用的就是它,后来发现这样并不能满足我的要求,因为这个方法在软键盘要弹还没弹时返回的是false,那个mWindowVisible是false的。通过看源码找到一个方案,就是在这种情况下,如果mInShown是true的话也返回true。反正我用这样一个改进后没有发现得到的状态时错的。
      这个方案后来被法二替代,不过两者各有优缺点。
法二:通过在InputMethodService中的showSoftInput和hideSoftInput方法中发送一个广播来告知应用程序软键盘的状态。应用程序要搞个intent filter,使这个广播只发向这个应用。状态有现成的,就在这两个方法的最后。在showSoftInput中,如果不是unchanged hidden就是弹出的状态;在hideSoftInput中,如果不是unchanged shown就是隐藏的状态。unchanged的含义是键盘弹出了,跳到search页面,或者弹出上下文菜单了,或者按了next按钮了,诸如此类。

你可能感兴趣的:(Android软键盘的状态获取)