35

My code for opening an input dialog reads as follows:

final AlertDialog.Builder alert = new AlertDialog.Builder(this);  
alert.setTitle("Dialog Title");  
alert.setMessage("Request information");  
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.edittextautotextlayout, null);
final EditText inputBox = (EditText) textEntryView.findViewById(R.id.my_et_layout);
alert.setView(inputBox);

This works fine except that I have to tap the text entry line before the soft keyboard appears.

Following the advice given here I have tried inserting:

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

but Eclipse objects that "the method getWindow() is not defined for the type AlertDialog.Builder".

It seems that the setOnFocusChangeListener code works for an AlertDialog object but not an AlertDialog.Builder. How should I modify my code to make the soft keyboard appear automatcially.

Community
  • 1
  • 1
prepbgg
  • 3,454
  • 9
  • 35
  • 46

14 Answers14

82

As long as you always need to show the keyboard immediately once the dialog opens rather than once a specific form widget inside gets focus (for instance, if your dialog just shows an EditText and a button), you can do the following:

AlertDialog alertToShow = alert.create();
alertToShow.getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
alertToShow.show();

Rather than calling .show() on your builder immediately, you can instead call .create() which allows you to do some extra processing on it before you display it onto the screen.

Natix
  • 13,037
  • 7
  • 49
  • 67
Defragged
  • 1,904
  • 15
  • 15
  • @Johnny This is the code to display the alert, so place it wherever you determine you need to show the alert. It's probably replacing an existing call to `alert.show()`. – Defragged Aug 12 '14 at 13:57
  • is shows the keyboard, but the focus is not in my `EditText`. Any ideas? – Georg Mar 04 '15 at 16:46
  • 4
    THE REAL PROBLEM IS that when you call to setSoftInputMode() before alert show() it layouts differently (it's strange...) - my custom views get ugly overlapped with Ok/Cancel buttons. So CALL setSoftInputMode() AFTER show()!!! – sberezin Oct 13 '15 at 11:26
  • Brilliant!! Thank you! – Ajji Dec 11 '16 at 07:48
  • Yeah, it's working great in Kotlin. Sheet man, you are awesome. – Jose Ricardo Citerio Alcala Apr 25 '19 at 14:38
16

This is in response to miannelle.

The following method is called when a menu option is selected:

private void addNote() {
    final Dialog dialog = new Dialog(this);
    dialog.setContentView(R.layout.textentryalertdialog);
    dialog.setTitle("Add note");
    TextView msgText = (TextView) dialog.findViewById(R.id.messagetext);
    msgText.setText("Whatever prompt you want");
    final EditText inputLine = (EditText) dialog.findViewById(R.id.my_edittext);
    Button okButton = (Button) dialog.findViewById(R.id.OKButton);
    okButton.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
            // app specific code
        }           
    });
    Button cancelButton = (Button) dialog.findViewById(R.id.CancelButton);
    cancelButton.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
        }           
    });
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    dialog.show();
}

The textentryalertdialog.xml file defines a linear layout containing

TextView android:id="@+id/messagetext" ...

EditText android:id="@+id/my_edittext" ...

Button android:id="@+id/OKButton" ...

Button android:id="@+id/CancelButton" ...

I hope this helps.

prepbgg
  • 3,454
  • 9
  • 35
  • 46
  • 1
    Code does not work on device which have a real keyboard (like Moto Droid). Anyone knows how to deal with that? – Xiao Feb 24 '12 at 08:19
6

With the encouragement of Mur Votema (see his answer above) I have answered my question by building a custom dialog based on the Dialog class. Unlike an alert based on AlertDialog.Builder such a custom dialog does accept the getWindow().setSoftInputMode(...) command and therefore allows the soft keyboard to be displayed automatically.

For guidance on building a custom dialog I found this web page and this especially helpful.

Artem Russakovskii
  • 20,170
  • 17
  • 87
  • 114
prepbgg
  • 3,454
  • 9
  • 35
  • 46
  • Thanks again to you and everyone else for your help. :) – prepbgg Nov 07 '10 at 20:36
  • Thanks! it works!, for my case my dialog have a recyclerview with items(with edittext) and i was trying with alertdialog with no success. y changed the alertdialog by a dialog and now the keyboard popups. – ingyesid Nov 04 '17 at 18:09
2

If you want to pop up dialog box along with soft key pad, so that user could free from tap on edit text inside dialog to show keypad, for example if you are going to take some value from dialog box, then use this simple code, it will solve your problem.

        public void onClick(final View v) 
        {   
             AlertDialog.Builder alert = new AlertDialog.Builder(v.getContext());                 
              alert.setIcon(R.drawable.smsicon);
              alert.setTitle(" Secrete Code");  
              alert.setMessage("Enter a Key for secrete text !");
              final EditText shft_val = new EditText(v.getContext()); 
              shft_val.setInputType(InputType.TYPE_CLASS_NUMBER);//changing the keyBoard to No only,restrict the string etc
              alert.setView(shft_val);

     //pOp Up the key pad on Edit Text  focus event

             shft_val.setOnFocusChangeListener(new OnFocusChangeListener()
             {
                public void onFocusChange(View arg0, boolean arg1)
                {  InputMethodManager inputMgr = (InputMethodManager)v.getContext().
                                    getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
                        }
                    });

                 alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() 
                 {  
                 public void onClick(DialogInterface dialog, int whichButton) 
                 {
                    //Your specific code... 
                 }
                 });
                 alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                     public void onClick(DialogInterface dialog, int which) {                       
                         dialog.dismiss();
                         return;   
                     }
                 });
                       alert.show();
                    }
Pir Fahim Shah
  • 9,541
  • 1
  • 73
  • 71
2

try using view

v.getWindow().setSoftInputMode( 
           WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
pengwang
  • 17,956
  • 32
  • 112
  • 167
  • Thanks for the suggestion. I tried that, but unfortunately I got the same error message ("the method getWindow() is undefined for the type View") – prepbgg Oct 30 '10 at 16:20
2

Have you tried to set focus on your EditText -> inputBox.requestFocus() or something like that?

Tima
  • 12,040
  • 22
  • 74
  • 121
  • 1
    Thanks for the suggestion. I tried inserting inputBox.requestFocus(); after alert.setView(inputBox);, but no joy! – prepbgg Oct 30 '10 at 16:24
  • ... and if you try to call requestFocus after alert.create() ? Because first dialog should be created and then edit can get focus, no?! – Tima Oct 30 '10 at 21:05
  • My code doesn't explicitly call create(). Presumably it is called indirectly by the statement "AlertDialog.Builder alert = new AlertDialog.Builder(this);" which definitely comes before any other reference to alert. – prepbgg Oct 30 '10 at 21:15
  • Yes, the code shown in my original question continues "alert.setPositiveButton(...); alert.setNegativeButton(...); alert.show();". Following this with "inputBox.requestFocus()" does nothing. Trying "inputBox.setPressed(true);" just highlights the text box in green. I can't see any other relevant methods to try. – prepbgg Oct 31 '10 at 11:08
  • i'm not sure, but probably it's not possible to get access to a view, which was added to builder (http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/app/AlertDialog.java;h=021dc2e39f210d1e8c39f2380e83fd986ddf4d54;hb=edbabeb7fabfb3c7793b565cdaaf656e5e332efe) ....... why don't you try to use custom dialogs then?! another idea to create your own alertdialog.builder extending original alertdialog.builder and having member view in it. – Tima Oct 31 '10 at 13:06
  • I'm afraid that would be above my pay grade! (I think Android needs something like Visual Basic to make things easier for amateurs like me ... I've even found HTML+DHTML+Javascript much easier to use (and amazingly powerful.)) – prepbgg Nov 01 '10 at 11:14
  • I had had the same thoughts on this weekend. But ... maybe this link will help you to create a custom dialog http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog it's not so difficult. Wish you much luck – Tima Nov 01 '10 at 11:54
  • Thanks for your encouragement. I'll have a look at your suggestion and report back. – prepbgg Nov 02 '10 at 08:33
  • I've read the section on Custom Dialogs in the page you referred me to. After describing how to build a custom dialog based on the Dialog class, this goes on to discuss customising a dialog based on AlertDialog.Builder (much as I have already done) and says "using an AlertDialog for your custom layout lets you take advantage of built-in AlertDialog features like managed buttons". This suggests that unless I use AlertDialog.Builder I won't get "Ok" and "Cancel" buttons. So I am flummoxed as to which way to proceed! – prepbgg Nov 02 '10 at 20:25
  • I see that the "Creating A Custom Dialog" notes say that "an AlertDialog is created easiest with the AlertDialog.Builder class". This suggests that perhaps you don't have to use AlertDialog.Builder. I wonder if there is a tutorial anywhere on how to build an AlertDialog object without using AlertDialog.Builder. As you can probably tell, I'm floundering here. – prepbgg Nov 02 '10 at 20:36
  • 1
    With the help of a couple of tutorials (http://www.helloandroid.com/tutorials/how-display-custom-dialog-your-android-application and http://blog.androgames.net/10/custom-android-dialog/) I've created a custom Dialog object which emulates the default AlertDialog.Builder object well (so far as I can tell) and which (unlike an AlertDialog.Builder object) accepts the getWindow().setSoftInputMode(...) command. Bingo! It wasn't so difficult, I suppose, but it's an extraordinarily fiddly thing to have to do just to allow the automatic display of the soft keyboard. – prepbgg Nov 06 '10 at 20:54
1

I know, this Question is really old, but since I've tried about 20 different so called 'solutions', I will post, what actually only worked for me finally.

This answer is based on the answer of Pir Fahim Shah, who pointed me in the right direction (Thanks):

Make sure, you put this in the onCreate of your activity, so that forced keyboards are being hidden, when dialog is closed:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

then create a dialog like this:

    AlertDialog.Builder builder = new Builder(this);
    builder.setTitle("title");
    final EditText input = new EditText(this);
    input.setText("text");
    input.setSelection(input.getText().length()); // set cursor to end
    builder.setView(input);
    input.setOnFocusChangeListener(new OnFocusChangeListener()  {
       public void onFocusChange(View v, boolean hasFocus) { 
           if(hasFocus) {
               InputMethodManager inputMgr = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
               inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
           }
       }
    });
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            // do something here
            dialog.dismiss();
        }
    });
    builder.setNegativeButton("Cancel", null);
    builder.show();
sec_aw
  • 1,584
  • 14
  • 26
1

try using inputBox

inputBox.getWindow().setSoftInputMode( 
               WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Aaron Saunders
  • 31,625
  • 5
  • 54
  • 74
  • Thanks for the suggestion. However, when I try that Eclipse says "the method getWindow() is undefined for type EditText" – prepbgg Oct 30 '10 at 13:18
1

I create an AlertDialog and use a custom view which contains an EditText. And I want the soft keyboard to be shown when the dialog is shown and to be hidden whether the user clicks OK button or somewhere outside the dialog.

This piece of code is from androidx.perference.PreferenceDialogFragmentCompat and I clean up a little.

final AlertDialog.Builder builder = new AlertDialog.Builder(context)
        .setTitle(mDialogTitle)
        .setPositiveButton(mPositiveButtonText, null)
        .setNegativeButton(mNegativeButtonText, null);

View contentView = LayoutInflater.from(context).inflate(resId, null);

mEditText = contentView.findViewById(android.R.id.edit);

/**
 * From PreferenceDialogFragmentCompat.needInputMethod
 * <p>Note: If your application targets P or above, ensure your subclass manually requests
 * focus (ideally in {@link #onBindDialogView(View)}) for the input field in order to
 * correctly attach the input method to the field.
 */
mEditText.requestFocus();

builder.setView(contentView);

final Dialog dialog = builder.create();
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

// This is not from PreferenceDialogFragmentCompat and I add it.
// It seems the soft keyboard won't get dismissed on some old devices without this line.
dialog.setOnDismissListener {
    dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

dialog.show();

You don't need to modify Manifest. It automatically focuses to the EditText and will be dismissed whether you click dialog action buttons or somewhere outside the dialog.

Dewey Reed
  • 3,162
  • 1
  • 20
  • 30
1

I think you almost had it working in your original question. Try creating a final AlertDialog to call getWindow() on, e.g.

// Create the dialog used to modify the mailbox alias
final AlertDialog dialog = alert.create();

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

I've tested this code and the keyboard now appears automatically on most of my devices, including:

  • Samsung Galaxy Tab OS 2.2
  • Samsung Galaxy S OS 2.1
  • HTC Sensation OS 2.3.4

Some other comments on this solution:

1) Check if you've got anything in your XML already to request the focus, as that may stop this code working (according to Ted in the question you link to).

2) This code doesn't seem to work on my HTC G2 running OS 2.3.4. I guess this is because it has a physical keyboard, and maybe the WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE option doesn't work with it?

I also tried SOFT_INPUT_STATE_VISIBLE (without the ALWAYS), but that stopped the keyboard appearing automatically.

3) You may also want to add code so the user can press the Done button on the keyboard to submit the changes, e.g.

inputAlias.setOnKeyListener(new OnKeyListener()
{
  @Override
  public boolean onKey(View v, int keyCode, KeyEvent event)
  {
    if (keyCode == KeyEvent.KEYCODE_ENTER &&
        inputAlias.isFocused() &&
        inputAlias.getText().length() != 0)
    {
      // Save the new information here

  // Dismiss the dialog
      dialog.dismiss();
      return true;
    }
    return false;
  }
});
Dan J
  • 24,430
  • 17
  • 95
  • 168
0

In the following code snippet I show how to host an arbitrary LinearLayout in a DialogFragment. One using AlertDialog (where the soft keyboard doesn't work) and another way without using AlertDialog (where the soft keyboard does work!):

public static LinearLayout createLinearLayout(Context context)
{
    LinearLayout linearLayout = new LinearLayout(context);
    linearLayout.setOrientation(LinearLayout.VERTICAL);
    linearLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    String html;
    html = "<form action=search method=get >\n";
    html += "Google Search: <input name=q value=\"Johnny Depp\" /><br/>\n";
    html += "<input type=submit name=output value=search /><br/>\n";
    html += "</form>\n";
    WebView webView = new WebView(context);
    webView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebChromeClient(new WebChromeClient());
    webView.setWebViewClient(new WebViewClient());
    webView.loadDataWithBaseURL("http://www.google.com", html, "text/html", "UTF-8", null);
    linearLayout.addView(webView);
    return linearLayout;
}

public void showWithAlertDialog()
{
    DialogFragment dialogFragment = new DialogFragment()
    {
        public Dialog onCreateDialog(Bundle savedInstanceState)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder
                .setTitle("With AlertDialog")
                .setView(createLinearLayout(getActivity()));
            return builder.create();
        }
    };
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    dialogFragment.show(fragmentTransaction, "dialog");
}

public void showWithoutAlertDialog()
{
    DialogFragment dialogFragment = new DialogFragment()
    {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            getDialog().setTitle("Without AlertDialog");
            getDialog().setCanceledOnTouchOutside(false);
            return createLinearLayout(getActivity());
        }
    };
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    dialogFragment.show(fragmentTransaction, "dialog");
}
Stephen Quan
  • 15,118
  • 3
  • 69
  • 63
0

I found this worked in an Alert Dialog called from different places

        case R.id.birthyear:
        case R.id.ymax:
            input.setInputType(InputType.TYPE_CLASS_NUMBER);
            break;

Mind you I tried lots of other things too. Seems delicate.

user462990
  • 5,162
  • 3
  • 31
  • 33
0

.setView() will automatically bring up the keyboard in a dialog. Note the "final" on the EditText itself. IMPORTANT!

AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Random Title...");
alert.setMessage("Type a name");

final EditText input = new EditText(this);

//Set input focus (which opens the android  soft keyboard)
alert.setView(input);   
input.setHint("My Name is...");
//Set keyboard type
input.setInputType(InputType.TYPE_CLASS_TEXT); 

//add button onclick handlers...

alert.show();

I think a lot of people are really overdoing it with all the functions... This is fairly universal and work great. And it won't bloat your code.

0

Hi Prepbgg there is actually an alternative way to what you've done. I actually had to use mine within my ArrayAdapter. What i did was pass the context of the activity into the arrayadapter then call it to access getWindow() something like this:

NoteArrayAdapter(Activity _activity, int _layout, ArrayList<Note> _notes, Context _context) {
  callingNoteListObj = (NoteList) _context;
}

// withiin getView

callingNoteListObj.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

// within parent activity's onCreate()
thisObject = this;

//within my parent activity's fillData() (NoteList)
adapter =  new NoteArrayAdapter(activity, R.layout.channel_note_list_item, noteList, thisObject);
wired00
  • 12,270
  • 6
  • 65
  • 65