Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A better solution for an AlertDialog with an EditText

I would like an AlertDialog with an EditText field in it to accept input. This in itself is pretty straight-forward. However there are a few "obvious" features that I would like as fallout from this request. I'll take them one-by-one. I am looking for anyone that has a simpler solution to these things. I am guessing the solution is, "Write your own custom dialog you lazy bum."

AlertDialog with an EditText

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

Yay, works great. It'd sure be nice if that input field got focused right away (and show the keyboard), right?

AlertDialog with focused EditText The following code would be after create() and before 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);
    }
});

Nice job... I guess. Now that I have this focused input it'd be nice if it respected the inputs IME option...

AlertDialog with focused EditText with a custom IME Option

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

Now that's really not a great solution (repeated code) but it works...

Do people have a better way of solving this problem, or is it really that rare to ask a user for a small piece of information in a dialog, or am I just a winer and should go write my own dialog?

like image 224
xbakesx Avatar asked Sep 05 '12 20:09

xbakesx


2 Answers

As per comments on the OP:

You do not have to have such repeated code in the OnEditorActionListener. Instead of repeating the code, you can tell the OS to click the "Ok" button when it is activated.

Something like this:

public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
    dlg.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); // Click OK button
    return true;
}

Overall I would say you are taking the right approach (documentation about collecting information through dialogs). As I mentioned in a comment, the OS uses an AlertDialog w/ EditText for adding dictionary words (to the user dictionary), so this is an expected functionality in the OS.

like image 132
Cat Avatar answered Nov 12 '22 23:11

Cat


You can always switch to an Activity with Theme.Dialog theme or a DialogFragment which gives you a lot more freedom in tuning your widgets. AlertDialogs are probably better for displaying information. Hope this helps.

like image 2
Egor Avatar answered Nov 13 '22 00:11

Egor