显示对话框软键盘

85

我正在显示一个带有编辑文本视图的对话框。然而,只有当用户在编辑视图内按下时,软键盘才会打开。因此,我尝试使用以下代码调用InputMethodManager。

InputMethodManager imm =
 (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(dialogField,0);

dialogField是输入字段。但是我应该在什么时候做这件事呢?我尝试在对话框的onStart()方法中做,但是没有任何反应。我之前也试图先请求对话框字段的焦点,但是仍然没有改变。

我还尝试了这段代码

dialogField.setOnFocusChangeListener(new View.OnFocusChangeListener()
{
    public void onFocusChange (View v, boolean hasFocus)
    {
        if (hasFocus)
        {
            Main.log("here");
            dialogInput.getWindow().setSoftInputMode(
              WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            /*
                InputMethodManager mgr =
                  (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                mgr.showSoftInput(dialogField,0);
            */
        }
    }
});

两个版本都会出现这种情况。但是没有软键盘会弹出。Main.log只是一个日志,它告诉我函数确实被调用了。是的,它被调用了。

我可以在对话框打开之前使用SHOW_FORCED标志获取键盘。但是然后它将不会在退出时关闭。并且我只能在显示对话框之前执行此操作。在任何回调内部都不起作用。


你尝试过使用SHOW_IMPLICIT标志吗? - Telmo Marques
1
这是我一直苦苦挣扎却无法正确运行的东西。 - Thomas
是的,我尝试了SHOW_IMPLICIT标志。文档确切地说,如果用户需要为TextEdit输入,则应调用showSoftInput。但是如何实现呢? - Rene
这个问题已经在这里得到了解答,对我来说非常有效。 - Shawn Lauzon
5个回答

201

非常好的问题,我也在尝试做这件事并找到了解决方案。

使用对话框构建器类AlertDialog.Builder,您将需要像这样调用对话框:






AlertDialog.Builder builder = new AlertDialog.Builder();
AlertDialog dialog;

builder.set...

dialog = builder.create();
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();

这对我很好用。

注意:您必须导入 android.view.WindowManager.LayoutParams; 以获取那里的常量值。


1
我确实想知道这会如何影响对话框关闭后窗口的行为...别忘了窗口包含对话框和您的活动。 - Alex.F
6
提醒所有有相同问题的人注意:在调用show()之前必须先调用setSoftInputMode() - Abbas
2
对我而言,使用“SOFT_INPUT_STATE_ALWAYS_VISIBLE”起作用。 - abbasalim
2
哇,非常感谢!我们能否在SO上添加捐赠或贡献按钮以表达感激之情? - Joel Broström
1
终于有答案了!对于任何想要从自定义对话框类中使用它的人,只需在onCreate()方法中调用getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE)即可。 - Nekomajin42
显示剩余2条评论

17
 AlertDialog dialog = new AlertDialog.Builder(this).create();
    dialog.show();
    Window window = dialog.getWindow();
    window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

2
哥们儿,你太棒了!那个windows.cl3wrFlags这一行非常重要。我查看了每一个stackoverflow的答案,但是其他地方都没有提到这一行。谢谢你啊! - FreakyLearner
1
请注意,在Android 4-8上,在调用dialog.show()之后再调用dialog.getWindow().setSoftInputMode()会产生一个不好的副作用:对话框在配置更改后仍然停留在屏幕上,仍然与已销毁的Activity/Fragment绑定。 - gmk57
当您拥有一个使用适配器(嵌套EditText)的列表、分页或其他视图时,AlertDialog会设置这些标志,以便不会触发软输入。只需清除标志并设置软输入模式即可。 - Hank Chan

8

Kotlin

这是已经测试过的代码。

val dialog = AlertDialog.Builder(requireContext()).apply {
    setTitle(…)
    setView(editText)
    setPositiveButton(…)
    setNegativeButton(…)
}
val window = dialog.show().window
window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)

确保您从show()方法访问window属性。从create()方法获取window返回null,导致键盘无法显示。

androidx.appcompat.app.AlertDialog导入AlertDialog。从android.view导入WindowManager


3
这是我的解决方案,对话框方面效果很好。
txtFeedback.requestFocus();
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

也许您需要在AndroidManifest.xml中的活动标签中添加此代码,以便在对话框关闭时关闭键盘。
android:windowSoftInputMode="stateAlwaysHidden"

谢谢。唯一的解决方案对我有用。在我的情况下,我使用 Dialog 而不是 AlertDialog - Rumit Patel

1

Kotlin实现的对话框片段

重写onStart方法

override fun onStart() {
    super.onStart()
    dialog.window?.
    setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
    )
}

如果您想在关闭后进行解除操作,则可以使用以下代码覆盖dismiss方法。
override fun onDismiss(dialog: DialogInterface?) {
val inputMethodManager = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(activity?.currentFocus?.windowToken, InputMethodManager.HIDE_IMPLICIT_ONLY)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接