软键盘问题汇总
软键盘在Android中是重要的输入设备,如果我们对其进行友好化优化的话,对提高用户体验有大大的帮助。
1. InputMethodManager
InputMethodManager是软键盘的管理类,我们可以用它来控制软键盘的展开、隐藏等操作。
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
//隐藏软键盘
imm.hideSoftInputFromWindow(getActivity().getWindow().getDecorView().getWindowToken(), 0);
//切换键盘
if(imm.isActive()){ imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,InputMethodManager.HIDE_NOT_ALWAYS);
}
2. windowSoftInputMode
WindowSoftInputMode是控制软键盘的启动模式,一般在theme 或者manifest中设置
值 | 描述 |
---|---|
stateUnspecified | 软键盘的状态(是否它是隐藏或可见)没有被指定。系统将选择一个合适的状态或依赖于主题的设置。这个是为了软件盘行为默认的设置。 |
stateUnchanged | 软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。 |
stateHidden | 当用户选择该Activity时,软键盘被隐藏——也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。 |
stateAlwaysHidden | 软键盘总是被隐藏的,当该Activity主窗口获取焦点时 |
stateVisible | 软键盘是可见的,当那个是正常合适的时(当用户导航到"Activity主窗口时) |
stateAlwaysVisible | 当用户选择这个Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。 |
adjustUnspecified | 它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。 |
adjustResize | 该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间 |
adjustPan | 该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。 |
解决Andriod软键盘出现把原来的布局给顶上去的方法
//在mainfest.xml中,对那个Activity加:
<activity android:name=".activity.HomeActivity"
android:windowSoftInputMode="adjustPan|stateHidden"/>
3.WindowManager.LayoutParams.softInputMode
WindowManager.LayoutParams.softInputMode 是Window上的属性,当设置其属性时,如果之前在主题上设置上windowSoftInputMode将会override。如果采用其他许多办法无法关闭显示软键盘,可以设置WindowManager.LayoutParams.softInputMode,将会起到想不到的好效果
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
softInputMode | 描述 |
---|---|
SOFT_INPUT_MASK_STATE | 软输入区域是否可见 |
SOFT_INPUT_STATE_UNSPECIFIED | 未指定状态 |
SOFT_INPUT_STATE_UNCHANGED | 不要修改软输入法区域的状态 |
SOFT_INPUT_STATE_HIDDEN | 隐藏输入法区域(当用户进入窗口时) |
SOFT_INPUT_STATE_ALWAYS_HIDDEN | 当窗口获得焦点时,隐藏输入法区域。 |
SOFT_INPUT_STATE_VISIBLE | 显示输入法区域(当用户进入窗口时) |
SOFT_INPUT_STATE_ALWAYS_VISIBLE | 当窗口获得焦点时,显示输入法区域 |
SOFT_INPUT_MASK_ADJUST | 窗口应当主动调整,以适应软输入窗口 |
SOFT_INPUT_ADJUST_UNSPECIFIED | 未指定状态,系统将根据窗口内容尝试选择一个输入法样式 |
SOFT_INPUT_ADJUST_RESIZE | 当输入法显示时,允许窗口重新计算尺寸,使内容不被输入法所覆盖。不可与SOFT_INPUT_ADJUSP_PAN混合使用;如果两个都没有设置,系统将根据窗口内容自动设置一个选项 |
SOFT_INPUT_ADJUST_PAN | 输入法显示时平移窗口。它不需要处理尺寸变化,框架能够移动窗口以确保输入焦点可见。不可与SOFT_INPUT_ADJUST_RESIZE混合使用;如果两个都没有设置,系统将根据窗口内容自动设置一个选项。 |
SOFT_INPUT_IS_FORWARD_NAVIGATION | 当用户转至此窗口时,由系统自动设置,所以你不要设置它。当窗口显示之后该标志自动清除 |
4.InputType
我们使用EditText有时为了提高用户体验,在弹出软键盘时需要设置键盘的面板状况,有时需要展示中文键盘,数字键盘,英文键盘等等。
可以设置InputType。EditText的InputType可以输入两种类型,一种EditorInfo,一种是InputType。EditorInfo是InputType实现类
Android并没有提供设置默认的输入状态的接口,但我们可以通过如下方法一样能够达到想要的效果:
InputType可以在Xml设置,或者直接在代码中设置。
默认数字键盘
mEditText.setInputType(EditorInfo.TYPE_CLASS_NUMBER);
默认中文键盘
mEditText.setInputType(EditorInfo.TYPE_CLASS_TEXT);
默认英文键盘
mEditText.setInputType(EditorInfo.TYPE_TEXT_VARIATION_URI);
5.ImeOption
改变输入法中回车按钮的显示内容,如果回车按钮是执行搜索功能,则回车按钮上显示”搜索”,如果是执行发送功能,则显示”发送”,如果是下一步,则显示”下一步”。
/**
*
* IME_ACTION_SEARCH 搜索
* IME_ACTION_SEND 发送
* IME_ACTION_NEXT 下一步
* IME_ACTION_DONE 完成
*/
mInputEditTxt.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
6.关闭软键盘的N中方法
- 方式一:InputMethodManager
EditText edit=(EditText)findViewById(R.id.edit);
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edit.getWindowToken(),0);
- 方式二:clearFocus 失去焦点
EditText edit=(EditText)findViewById(R.id.edit);
edit.clearFocus();
- 方式三:InputType 默认EditText始终不弹出软键盘
EditText edit=(EditText)findViewById(R.id.edit);
edit.setInputType(InputType.TYPE_NULL);
7.KEYCODE
在软键盘输入中我们需要监听我们按的键,我们可以用OnkeyListener监听按键。例如
KeyEvent.KEYCODE_Z、KeyEvent.KEYCODE_ENTER等按键。
mInputEditTxt.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
System.out.println("手指弹起时执行确认功能");
return true;
}
return false;
}
});