记录一次Android EditText无法自动弹出和关闭键盘的坑

2,834 阅读1分钟

问题:在Activity或者Dialog、DialogFragment中,点进去EditText可以获取到焦点,但是输入法软键盘没有弹出来,需要手动点下EditTex才会弹出。

在布局文件设置focusable和focusableInTouchMode不生效

android:focusable="true"
android:focusableInTouchMode="true"

使用requestFocus()方法获取焦点也不生效

editText.isFocusable = true
editText.isFocusableInTouchMode = true
editText.requestFocus()

Activity中无法自动弹出键盘的解决方法

项目中手动弹出键盘的方法:

  public static void showSoftInput(Activity activity) {
        if (activity != null) {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null && imm.isActive() && activity.getCurrentFocus() != null) {
                imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }

需要使用Handler或postDelayed等方法延迟弹出输入法,避免界面还没绘制完毕就请求焦点导致不弹出键盘。

 editText.postDelayed({
      xxxUtils.showSoftInput(this)
 }, 500)

Dialog中无法自动弹出键盘的解决方法

Dialog中比Activity稍微麻烦。

需要加上下面的一行代码,使得弹出对话框时软键盘随之弹出

dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)

另外,用下面这行代码,弹出对话框时需要点击输入框才能弹出软键盘

dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)

Dialog中无法手动关闭键盘的解决方法

项目中原来关闭键盘的方法:

    public static void hideSoftInput(Activity activity) {
        if (activity != null) {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null && imm.isActive() && activity.getCurrentFocus() != null) {
                imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }

分析原因发现是获得焦点的控件在Dialog上,FragmentActivity上没有任何控件获取焦点,所以使用上面关闭键盘方法的时候,会发现activity.getCurrentFocus()的时候返回了null。 正确操作是hideSoftInputFromWindow方法中改为传入当前View的windowToken。

修改关闭键盘的方法:

    public static void hideSoftInput(Activity activity, View view) {
        if (activity != null) {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null && imm.isActive() && view.getWindowToken() != null) {
                imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    }
​