Android 关于软键盘的显示和隐藏爬坑记录
之前项目中关于软键盘的隐藏和显示在BaseAcitivity中做的处理是点击空白位置隐藏软键盘
/**
* 点击空白位置 隐藏软键盘
*/
public boolean onTouchEvent(MotionEvent event) {
if (null != this.getCurrentFocus()) {
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
}
return super.onTouchEvent(event);
}
getCurrentFocus()方法作用是获取当前焦点所在的View,一般情况是不会为null的,但是写代码还是要严谨...
貌似简单布局下的就完全够用了... (强行解释)
今天写的布局是EditView下面是还有一层RecyclerView,喔不对,应该是同级别的不然RecyclerView最后的条目会被遮挡住,这个时候上面的方法貌似就不够用了...
为什么?这个方法在Activity做的事件监听,到RecyclerView的时候Activity的OnTouchEvent已经失效了可以理解被已经被消费了,RecyclerView的OnTouchEvent优先权高于Activity。
所以我们在onTouchEvent中做的处理也不会被执行了。
既然这样我们依旧手动去控制软键盘的显示的隐藏,去监听RecyclerView的滚动事件
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
//滚动时当软键盘显示时隐藏
if (newState != 0 && UtilsHelper.isShowSoftInput(TimeLineDetailsActivity.this, mEditComment) == true) {
UtilsHelper.hideSoftInput(TimeLineDetailsActivity.this, mEditComment);
mEditComment.clearFocus();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
newState为recyclerView的滚动状态:
public static final int SCROLL_STATE_IDLE = 0; 没有滚动静止状态
public static final int SCROLL_STATE_DRAGGING = 1; 正在被外部拖拽,一般为用户正在用手指滚动
public static final int SCROLL_STATE_SETTLING = 2; 自动滚动
也就是说在非0的情况下即为滚动状态,同时我们还要判断滚动时软键盘是否为显示状态。
/**
* 获取软键盘状态
* @param context
* @return
*/
public static boolean isShowSoftInput(Context context,View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
//获取状态信息
return imm.isActive(view);//true 打开
}
isActive(View view) ,isActive()这俩个方法,开始没有传view,发现是可行的,软键盘可以隐藏,后来打log发现这个一直返回的是true啊,难怪!最后测试给参数view,在软键盘隐藏的时候为false,显示的时候未true,这就很明了了。
public boolean isActive (View view)视图为当前输入的激活视图时返回真。
public boolean isActive ()输入法中的任意视图激活时返回真。
意思就是如果该view是输入法的活动view则返回true也可以理解为由该view触发的软键盘弹出则返回true,反之为false。
妥妥的,问题解决。
同时我在google的时候看到好多blog写的方法
if(getWindow().getAttributes().softInputMode==WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) 无效!!!
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
这种方法貌似可以,可能针对场景不同而异,并未做更多测试。
就是改变输入法状态,如果当前未显示则显示出来。如果显示出来,则隐藏
还有一种是动态计算布局来判断软键盘是否显示(并未做测试)
附软键盘手动显示、隐藏、状态判断工具类:
public class UtilsHelper {
/**
* 显示软键盘
* @param context
* @param view
*/
public static void showSoftInput(final Context context, final View view) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
}, 998);
}
/**
* 隐藏软键盘
* @param context
* @param view
*/
public static void hideSoftInput(Context context, View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
}
/**
* 获取软键盘状态
* @param context
* @return
*/
public static boolean isShowSoftInput(Context context,View view) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
//获取状态信息
return imm.isActive(view);//true 打开
}
}
本文完,如有问题、错误欢迎评论指出谢谢!