Android show/hide softKeyboard
最近项目中需要有一个地方隐藏键盘和显示键盘。其实是一个比较简单的问题,但是由于我们项目架构的原因。一个Activity中内嵌了很多个Fragment,通过事件去驱动不同的Fragment展现出来。举个例子,注册流程实际上是一个Activity,然后其中包含了ResetPasswordFragment,forgetPasswordFramgent,loginFragment等等。如果用户在Login界面的EditView输入账号密码的时候,通过back键恢复到了上一个Activity的时候,键盘是无法隐藏掉的。
为了解决这个问题,我的第一次解决的方案是这样。通过在VM层中添加一个变量hideSoftKeyboard,然后给XML设定一个自定义的BindingAdapter,传入这个变量。
@BindingAdapter("showSoftKeyboard")
public static void showSoftKeyboard(View view, Boolean showSoftKeyboard) {
if (!showSoftKeyboard) {
InputMethodManager imm = (InputMethodManager) editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
}
但是这样会出现一个问题,即toggleSoftInput是一个二元的开关,第一次开,第二次关。很蛋疼。下来我去Google寻找答案。找到了一个比较靠谱的SOF。小哥先吐槽了一下Android的API设计,确实比较蛋疼,居然没有给一个相应的API来控制展示和隐藏。需要通过InputMethodManager来接管,但是还需要传入一个Context才能获得IMM,获得后还需要具体的View才可以设置键盘的隐藏。按理说,系统直接提供一个方法**Keyboard.hide()和Keyboard.show()**不就挺好。在需要的时候就直接展现和隐藏就好。我在想这可能是因为,Android为了将这个控制权放到系统层面,这样可以避免恶意软件强制系统其他应用不会隐藏按键,导致用户体验崩裂。
既然这样,我就采用了另外的方法,做了一个Util类,来控制显示和隐藏。
public class KeyBoardUtil {
private KeyBoardUtil() {}
public static void hideSoftKeyboard(Activity activity) {
View focusedView = activity.getCurrentFocus();
if(focusedView != null) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(focusedView.getWindowToken(), 0);
}
}
public static void showSoftKeyboard(View view) {
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
view.requestFocus();
imm.showSoftInput(view, 0);
}
在需要展示和隐藏的地方直接调用去传递对应的参数即可。这个时候我们的BindingAdapter就可以改造成这样:
@BindingAdapter("showSoftKeyboard")
public static void showSoftKeyboard(View view, Boolean showSoftKeyboard) {
if (showSoftKeyboard) {
KeyBoardUtil.showSoftKeyBoard(view);
} else {
Context context = view.getContext();
if (context instanceof Activity) {
Activity act = (Activity)context;
KeyBoardUtil.hideSoftKeyBoard(act);
}
}
}