使用带有EditText的AlertDialog.Builder时,软键盘不会弹出

时间:2010-08-11 04:14:48

标签: android android-softkeyboard android-input-method

我正在使用 AlertDialog.Builder 来创建一个输入框,并使用EditText作为输入法。

不幸的是,虽然 EditText 处于焦点状态,但软键盘不会弹出,除非您再次明确触摸它。

有没有办法强制它弹出?

我在(AlertDialog.Builder).show(); 之后尝试了以下,但无效。

InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(input, InputMethodManager.SHOW_FORCED);

任何人都可以提供帮助吗?

谢谢!

15 个答案:

答案 0 :(得分:213)

我做了这样的事情

AlertDialog.Builder b = new AlertDialog.Builder(this);//....
AlertDialog dialog = b.create();

dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

dialog.show();

答案 1 :(得分:25)

我设法解决了这个问题:

Dialog = builder.create();
Dialog.show();
Dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
Dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

答案 2 :(得分:21)

我发现相同的代码在平板电脑上正常工作,键盘确实会弹出,但在手机上则没有,因此进一步研究似乎指向“调整”选项。

我正在使用它,感觉更清洁。

AlertDialog d = builder.create();
d.getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
d.show();

答案 3 :(得分:7)

就我而言,在显示对话框时我能够显示键盘的唯一方法是添加到我的DialogFragment

@Override
public void onResume() {
    super.onResume();
    getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    myEditText.requestFocus();
}

请注意 SOFT_INPUT_STATE_ALWAYS_VISIBLE ,而不是 SOFT_INPUT_STATE_VISIBLE

来自文档:

int SOFT_INPUT_STATE_ALWAYS_VISIBLE
Visibility state for softInputMode: please always make the soft input area visible when this window receives input focus.

答案 4 :(得分:6)

当您调用showDialog以显示使用onCreateDialog中的AlertDialog创建的对话时

你应该把代码放在这里

    @Override
protected void onPrepareDialog (int id, Dialog dialog, Bundle args)
{
    TextView editText=(TextView) dialog.findViewById(R....);

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
       @Override
       public void onFocusChange(View v, boolean hasFocus) {
         if (hasFocus) {
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
         }
       }
    });

}

答案 5 :(得分:5)

给出了一个更好的解决方案here

dialog.getWindow().clearFlags(
         WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
        |WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

没有解决方法。 EditText表现得与预期一致。

答案 6 :(得分:2)

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);

答案 7 :(得分:2)

就我而言,在显示对话框之前(创建对话框之后),我没有设置SoftInputMode。下面的代码为我工作,在显示对话框后设置SoftInputMode。

科特琳:

val dialog = MaterialAlertDialogBuilder(context) // Other builder code
                .create()
dialog.show()
dialog.window?.apply { // After the window is created, get the SoftInputMode
    clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
    clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
    setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}

Java:

AlertDialog dialog = MaterialAlertDialogBuilder(getContext()) // Other builder code
                .create();
dialog.show();
Window window = dialog.getWindow();
if(window != null){ // After the window is created, get the SoftInputMode
    window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
    window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}

我希望这对与我有相同问题的所有人有所帮助。

答案 8 :(得分:1)

已经回答here。使用OnFocusChangeListener为我工作。

答案 9 :(得分:0)

试试这个,它为我工作

如果要显示软键盘:

InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.showSoftInput(input.getWindowToken(), 0);

如果你想隐藏它:

  InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(input.getWindowToken(), 0);

答案 10 :(得分:0)

final AlertDialog.Builder alert = new AlertDialog.Builder(context);

final AlertDialog dialog = alert.show();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

答案 11 :(得分:0)

在调用AlertDialog.onCreate之后添加EditText时,会发生此问题。

https://developer.android.com/reference/androidx/appcompat/app/AlertDialog.Builder

AlertDialog类负责自动设置 android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM为您 根据对话框中的任何视图是否从中返回true View.onCheckIsTextEditor()。

您需要清除FLAG_ALT_FOCUSABLE_IM标志。

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 

由于AlertDialog.show在DialogFragment.onStart中被调用,因此您可以在DialogFragment.onStart中插入代码。

@Override
public void onStart() {
    super.onStart();
    getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}

或者,如果不使用DialogFragment,则可以使用Dialog.setOnShowListener。

dialog.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialog) {
        getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    }
});

答案 12 :(得分:0)

试试这个,它对我有用

    Window window = dialog.getWindow();
    if (window != null) { // After the window is created, get the SoftInputMode
        window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
        window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }

答案 13 :(得分:0)

我找到了一个简单可靠的解决方案,如果您的布局复杂且可编辑字段不在根目录中,只需在对话框布局的根目录上放置一个隐藏的 EditText,

<!-- Just to trick AlertDialog to not hide soft keyboard -->
<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone" />

这基本上是为了欺骗compat/androidx的this part

我曾经使用上面的 onResume 解决方案,但我无法使用更简单的 AlertDialog.Builder() API 来删除 AppCompatDialogFragment 的使用,但现在我可以简单地使用更简单的 API。

答案 14 :(得分:-1)

您能想象我从这里开始获得答案的过程,只是为了给出准确的答案。

首先让我指出InputMethodManager.showSoftInput不使用SHOW_FORCED标志。它仅使用0和SHOW_IMPLICIT。

解决方案1 ​​

在这里,我们了解到Android出现了问题。很多时候,由于某些不完整的初始化,Android函数无法运行。听起来很疯狂,但后来我认为android对象的行为不正常。普通对象在构造时已完全初始化,但android对象必须经过一系列函数调用:onCreate,onStart,onThis,onThat。

Android知道这一点,因此每个View都有一个post和postDelayed函数;在视图的消息队列上的哪个后期处理指令,势必会被处理。

以下是我项目中的有效示例。

src / jav / android / Util.java

package jav.android;

import android.app.*;
import android.content.*;
import android.graphics.*;
import android.view.*;
import android.view.inputmethod.*;


public class Util 
{   
    public static void showKeyboard(final Context ctx,final View view) 
    {
        Runnable r = new Runnable()
        {
            @Override public void run()
            {
                if(view.requestFocus()) 
                {
                 InputMethodManager imm = (InputMethodManager)ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
                 imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
                }
            }
        };

        view.post(r);
    }

    // Note that we dont need to use View.post() here
    public static void hideKeyboard(Context ctx,View view) 
    {
     InputMethodManager imm = (InputMethodManager)ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
    }
}

import android.app.*; import android.content.*; import android.graphics.*; import android.view.*; import android.view.inputmethod.*; public class Util { public static void showKeyboard(final Context ctx,final View view) { Runnable r = new Runnable() { @Override public void run() { if(view.requestFocus()) { InputMethodManager imm = (InputMethodManager)ctx.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } } }; view.post(r); } // Note that we dont need to use View.post() here public static void hideKeyboard(Context ctx,View view) { InputMethodManager imm = (InputMethodManager)ctx.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); } }

解决方案2

  1. 添加为xml作为EditText内容。这将确保EditText一开始便有重点。因此,您不必以编程方式进行请求,因此无需使用View.post(Runnable)。

    <...布局>               

  2. 使用InputMethodManager显示键盘。

    InputMethodManager imm =(InputMethodManager)ctx.getSystemService(Context.INPUT_METHOD_SERVICE);                  imm.showSoftInput(view,InputMethodManager.SHOW_IMPLICIT);

    摘要

我的上述回答回答了您的特定问题。但是,您可能会注意到键盘最初会弹出,但是在Activity最小化并弹出回来时,EditText会获得焦点,但键盘却丢失了。我遇到的另一个问题是当我按回时,我希望键盘永远消失,直到用户再次按下文本框。