一个更好的带有EditText的AlertDialog解决方案

5
我需要一个带有EditText字段的AlertDialog来接受输入。这本身就十分简单。然而,从这个请求中,我想要一些“显而易见”的功能。我将逐一列举它们。如果有人有更简单的解决方案,请告诉我。我猜测解决方案是,“自己写一个定制对话框吧,懒鬼。”
final EditText input = new EditText(context);
final AlertDialog dlg = new AlertDialog.Builder(this).
    setTitle("Title").
    setView(input).
    setCancelable(false).
    setPositiveButton(android.R.string.ok, new OnClickListener()
    {
        @Override
        public void onClick(final DialogInterface dialog, final int which)
        {
            /* Handle ok clicked */
            dialog.dismiss();
        }
    }).
    setNegativeButton(android.R.string.cancel, new OnClickListener()
    {
        @Override
        public void onClick(final DialogInterface dialog, final int which)
        {
            /* Handle cancel clicked */
            dialog.dismiss();
        }
    }).create();
dlg.show();

太好了,非常顺利。如果输入框能够立即聚焦(并显示键盘),那就太好了,对吧?

AlertDialog中的聚焦EditText 下面的代码将在 create()之后,在dlg.show()之前进行:

/** This requires API Level 8 or greater. */
dlg.setOnShowListener(new OnShowListener()
{
    @Override
    public void onShow(final DialogInterface dialog)
    {
        input.requestFocus();
        ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(input, 0);
    }
});

干得好...我猜。既然有了这个专注的输入,如果它能尊重输入的IME选项就更好了...

AlertDialog与一个聚焦的EditText和自定义的IME选项

input.setImeOptions(EditorInfo.IME_ACTION_DONE);
input.setOnEditorActionListener(new OnEditorActionListener()
{
    @Override
    public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event)
    {
        /** Same code here that goes in the dialog.setPositiveButton OnClickListener */
        dlg.dismiss();
        return true;
    }
});

现在这并不是一个很好的解决方案(重复代码),但它确实发挥了作用...
人们有更好的方法来解决这个问题吗?或者向用户在对话框中询问少量信息真的如此罕见,还是我只是在抱怨,应该去编写自己的对话框?

为什么不把所有重复的代码都移到一个方法中,例如 setUpImeDialog(AlertDialog dlg, EditText input) { ... } - Cat
@Eric 显然你会这样做。但是需要注意的是,你必须同时监听 IME 事件和点击“确定”请求,这并不是最理想的情况。 - xbakesx
1
可以用IME事件触发点击。像这样:dlg.getButton(DialogInterface.BUTTON_POSITIVE).performClick();。虽然它仍然是一个次要的事件,但它避免了重复的代码。(如果这就是你想要的,我可以把它添加为答案。) - Cat
@Eric,这确实使情况变得更好了。将它添加为解决重复代码问题的答案。希望它能帮助到其他人! - xbakesx
2个回答

7
根据对OP的评论:
在OnEditorActionListener中不必重复代码。你可以告诉操作系统在激活时点击“确定”按钮,而不是重复代码。
像这样做:
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
    dlg.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); // Click OK button
    return true;
}

总体而言,我认为您采取了正确的方法(通过对话框收集信息的相关文档)。正如我在评论中提到的那样,操作系统使用带有EditTextAlertDialog来添加词典单词(到用户词典中),因此这是操作系统中预期的功能。

2
你可以随时切换到使用 Theme.Dialog 主题的 ActivityDialogFragment,这将使你在调整小部件方面拥有更多自由。而 AlertDialogs 则更适合用于显示信息。希望这能有所帮助。

实际上,我不同意。文档展示了如何收集信息而不是仅仅显示它。另外,操作系统中还有一个例子:添加单词到字典中。 - Cat
@Egor 在任何人开始创建新的 Activity 之前,我认为他们都应该考虑创建一个带有自己布局的对话框,并通过这种方式实现他们想要的功能。 - xbakesx

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