前言
软键盘是Android进行用户交互的重要途径之一,Android应用开发基本无法避免不使用它。然而官方没有提供一套明确的API来获取诸如:软键盘是否正在展示、软键盘高度等。本篇将着眼如此,探索解决方案。
本系列文章:
通过本篇文章,你将了解到:
1、软键盘开启与关闭
2、软键盘界面适配
3、软键盘高度获取
1、软键盘开启与关闭
为方便起见,这里用键盘代替软键盘来说明。
平时使用最多的无非就是EditText控件,当点击EditText时键盘就会弹出,当点击底部导航栏返回按钮时键盘收起,如下:
device-2020-10-11-102755 (2).gif
既然已经有弹出、收起键盘的例子,那么找找其如何控制键盘的。
键盘弹出
先看看看看EditText如何弹出键盘的。
#TextView.java
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
...
final boolean touchIsFinished = (action == MotionEvent.ACTION_UP)
&& (mEditor == null || !mEditor.mIgnoreActionUpEvent) && isFocused();
if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
...
if (touchIsFinished && (isTextEditable() || textIsSelectable)) {
//获取InputMethodManager
final InputMethodManager imm = getInputMethodManager();
viewClicked(imm);
if (isTextEditable() && mEditor.mShowSoftInputOnFocus && imm != null) {
//弹出键盘
imm.showSoftInput(this, 0);
}
...
}
...
}
return superResult;
}
可以看出弹出键盘只需要两个步骤:
1、获取InputMethodManager 实例
2、调用showSoftInput(xx)
键盘关闭
InputMethodManager inputMethodManager = (InputMethodManager)view.getContext().getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
同样的,可以看出收起键盘只需要两步:
1、获取InputMethodManager 实例
2、调用hideSoftInputFromWindow(xx)
弹出/关闭 工具类
将弹出/关闭方法提取出来:
public class SoftInputUtil {
public static void showSoftInput(View view) {
if (view == null)
return;
InputMethodManager inputMethodManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
inputMethodManager.showSoftInput(view, 0);
}
}
public static void hideSoftInput(View view) {
if (view == null)
return;
InputMethodManager inputMethodManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
有几点需要注意的是:
1、inputMethodManager.showSoftInput(xx) 一般来说需要传入的View是EditText 类型的。如果传入其它View,需要进行额外的操作才能弹出键盘。
2、inputMethodManager.showSoftInput(xx) 、inputMethodManager. hideSoftInputFromWindow(xx) 两个方法的最后一个参数用来匹配关闭键盘时判断当初弹出键盘时传入的类型,一般填0即可。
3、inputMethodManager. hideSoftInputFromWindow(xx) 第一个参数传入的IBinder windowToken类型。每个Activity创建时候会生成windowToken,该值存储在AttachInfo里,因此对于同一个Activity里的ViewTree,每个View持有的windowToken 都是指向通过一个对象。
针对上述1、3点再补充一下:
对于1点:
假设当传入的View是Button类型时,需要设置Button.setFocusableInTouchMode(true),此时能够弹出键盘。
比较完善的做法是:还需要在onTouchEvent(xx)里弹出键盘、需要将Button与键盘关联。实际上就是模仿EditText的工作,系统都提供了EditText接收输入字符,没必要自己再整一套,因此弹出键盘时通常传入EditText。<