我正在使用AlertDialog显示一个输入框。当我调用AlertDialog.show()时,对话框内部的EditText会自动聚焦,但软键盘不会自动显示。

我如何使软键盘自动显示时,对话框显示?(并且没有物理/硬件键盘)。类似于当我按下Search按钮调用全局搜索时,会自动显示软键盘。


当前回答

我知道这个问题很老了,因为我认为使用扩展函数是一种更漂亮的方式来显示编辑文本的键盘

下面是我用来显示编辑文本键盘的方法。

芬兰湾的科特林代码: 只需要调用edittext.showKeyboard()

fun EditText.showKeyboard() {
  post {
    requestFocus()
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
  }
}

Java代码:

public static void showKeyboard(EditText editText) {
    editText.post(new Runnable() {
      @Override
      public void run() {
        editText.requestFocus();
        InputMethodManager imm = (InputMethodManager) editText.getContext()
            .getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
      }
    });
  }

其他回答

我有同样的问题,并解决了它与以下代码。我不确定它在有硬件键盘的手机上会有什么表现。

// TextEdit
final EditText textEdit = new EditText(this);

// Builder
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Enter text");
alert.setView(textEdit);

alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        String text = textEdit.getText().toString();
        finish();
    }
});

alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        finish();
    }
});

// Dialog
AlertDialog dialog = alert.create();
dialog.setOnShowListener(new OnShowListener() {

    @Override
    public void onShow(DialogInterface dialog) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT);
    }
});

dialog.show();

你可以在EditText上附加onFocusListener或在AlertDialog上附加onShowListener,并添加以下内容:

val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)

我的方法使用了Android 11+的新方法,也支持旧版本:

fun Fragment.showKeyboard() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        ViewCompat.getWindowInsetsController(requireView())?.show(WindowInsetsCompat.Type.ime())
    } else {
        val focusedView = view?.findFocus() ?: view?.apply { requestFocus() }
        val imm = (context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
        val isShowSucceeded = imm.showSoftInput(focusedView, InputMethodManager.SHOW_IMPLICIT)
        if(!isShowSucceeded) {
            imm.toggleSoftInputFromWindow(
                view?.windowToken, 0, InputMethodManager.HIDE_IMPLICIT_ONLY)
    }
}

}

这对我很有用。我为对话框设置了一个OnShowListener,在那个监听器中,我为文本字段设置了一个onFocusChangeListener,在那个FocusChangeListener中,我用100ms的延迟调用showSoftInput,然后删除FocusChangeListener,所以它只处理第一个焦点变化。

当调用dialog.show()时,OnShowListener被调用,它请求文本字段的焦点。当文本字段获得焦点时,将调用FocusChangeListener并最终显示键盘。

    val views = DialogBinding.inflate(layoutInflater) // layout with 'textfield'
    val dialog = MaterialAlertDialogBuilder(requireContext())
        .setTitle("Exercise")
        .setView(views.root)
        ...
        .create()
    dialog.setOnShowListener {
        views.textfield.onFocusChangeListener = View.OnFocusChangeListener { view, _ ->
            view.postDelayed({
                (view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(view, 0)
            }, 100)                
            views.textfield.onFocusChangeListener = null
        }
        views.repcount.requestFocus()
    }
    dialog.show()

只需将这一行添加到manifest文件必要的活动。

android:windowSoftInputMode=“stateVisible”