输入法
Android中输入法弹框是比较常见,但也时不时遇到各种问题。
- 页面已经退出了输入法的输入框莫名其妙的还在,经常在各种APP中遇到这种情况。
- 有时打开一个页面,需要输入内容,这时候如果自动弹出输入框,用户体验也比较好,但是有时候会出现输入框不能自动弹出或者弹出又立马收起的情况。
等等各种玄学问题。
1、EditText获得焦点自动弹出输入法
只需要设置两处即可让EditText自动弹出输入法,①设置EditText获得焦点调用requestFocus() ②Activity设置合适的SoftInputMode
1.1、EditText设置requestFocus()
最常见的情况是打开一个输入页面,上面有一个EditText需要用户输入内容。这时候期望自动弹出输入法输入框。
首先,需要设置EditText获得focus焦点。推荐在xml布局中添加对应一些属性。有一种方法属性的使用还是第一次见到,XML tag属性。应该是在布局加载的时候调用EditText对应的方法requestFocus():
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<requestFocus />
</EditText>看到很多博客都写还要添加其它几个属性设置为true,实际试了不加也行
//可忽略
android:focusableInTouchMode="true"
android:focusable="true"
android:focusedByDefault="true"除了在xml布局中设置还可以在Activity代码中设置,调用EditText实例这些方法,使其获得焦点。
mEditView.setFocusable(true);
mEditView.setFocusableInTouchMode(true);
//必要的方法,上面两个可以不调用也能获得焦点。
mEditView.requestFocus();1.2、Activity设置windowSoftInputMode
在AndroidManifest.xml中对应的Activity标签中添加属性android:windowSoftInputMode
<activity android:name=".activity.InputMethodActivity"
android:windowSoftInputMode="stateAlwaysVisible">还能通过代码的方式在Activity的中设置该属性:
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);1.3、Activity的windowSoftInputMode值意义
属性android:windowSoftInputMode一共有如下这些值可选,每个都有特定的意义,在不同的场景中选择合适的值。
1、"stateUnspecified"
软键盘的状态 (是否它是隐藏或可见 )没有被指定。系统将选择一个合适的状态或依赖于主题的设置。这个是为了软件盘行为默认的设置。
2、"stateUnchanged"
软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。
3、"stateHidden"
当用户选择该 Activity时,软键盘被隐藏——也就是,当用户确定导航到该 Activity时,而不是返回到它由于离开另一个 Activity。
4、"stateAlwaysHidden"
软键盘总是被隐藏的,当该 Activity主窗口获取焦点时。
5、"stateVisible"
软键盘是可见的,当那个是正常合适的时 (当用户导航到 Activity主窗口时 )。
6、"stateAlwaysVisible"
当用户选择这个 Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该 Activity时,而不是返回到它由于离开另一个 Activity。
7、"adjustUnspecified"
它不被指定是否该 Activity主 窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局 视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为 设置。
8、"adjustResize"
该 Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间
9、"adjustPan"
该 Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
2、EditText清除焦点隐藏输入法
输入完成之后,点击EditText之外的其它区域,自动收起输入法对提高用户体验是极好的。既然让EditText获得焦点能弹出输入法,那么移除EditText的焦点,输入法会不会自动收起呢?答案是不能。
模拟点击其它区域,移除EditText的焦点。
mButton.setOnClickListener((v) -> {
mEditView.clearFocus();
});经过实际测试,输入法没能收起。EditText确实移除了焦点。

可能有些APP的开发者就使用了这种方式来收起输入法,往往导致输入法还莫名其妙的仍然处于弹出状态。
3、InputMethodManager
使用InputMethodManager输入法管理类似乎更好的操作输入法。先通过getSystemService()获取实例:
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);3.1、打开输入法:showSoftInput
显示键盘
mInputMethodManager.showSoftInput(mEditView, 0);
3.2、关闭输入法:hideSoftInputFromWindow
隐藏键盘
mInputMethodManager.hideSoftInputFromWindow(mEditView.getWindowToken(),0);第二个参数flag一般为0即可,官方API中的说明:flags Provides additional operating flags. Currently may be 0 or have the {@link #SHOW_IMPLICIT} bit set.
可以实现操作软键盘的弹出和隐藏,注意EditText的焦点并没有发生变化。实际中可能需要更多的业务逻辑去处理各种情况。

3.3、获取输入法打开状态 ×××
似乎这里并不管用,无法正确获得输入法弹出或者收起的状态。
boolean isOpen = mInputMethodManager.isActive();4、结束
更多关于输入法及InputMethodManager相关的技术可以阅读Android源码,这里推荐几篇深入剖析输入法原理的技术博客:

