Showing keyboard automatically in Android dialogs

Share

Having the Android soft-input keyboard pop-up when a Dialog window is shown is not so straight forward as one would think. After exploring different solutions found on the web (with no success) I managed to create a solution of my own. This article is mainly a tutorial that will help you achieve the above task.

To make this easier to explain I created a small project that will be available for download at the end of the article.
The project setup is pretty simple, I have one activity with a button to show the dialog and the dialog itself (I use a custom Dialog). Without further details on how to create an Android project let’s jump straight to the interesting parts.

The Dialog
As I mentioned above I use a custom Dialog. To create a custom dialog you need to extend the Dialog class from Android. But before we get to the actual implementation I would like to talk about the layout we will use for the dialog because this is very important. The layout needs to respect 3 conditions in order to achieve the desired outcome :

  • The root layout needs to have an id (you need to get a reference to this layout);
  • You need a component that gets user input (most likely an EditText widget);
  • You need another component that can receive focus.

Here is the layout I created for my dialog :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/dlgRoot"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
 
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="My text : "
        android:textAppearance="?android:attr/textAppearanceMedium" />
 
    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="numberDecimal"
        android:selectAllOnFocus="true"
        android:text="123" >
    </EditText>
 
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:text="Ok" />
 
</LinearLayout>

As you can see, the root layout has the id dlgRoot, the widget that will get user input is the EditText with the id textView1 and the component that can receive focus is the button with id button1. You will notice that the components have some attributes that you probably didn’t know about, or you don’t use them, the first attribute is found in the EditText widget, it’s called android:selectAllOnFocus and , as it name says, it selects all the content of the EditText when the component receives focus. The second attribute, witch is very important, is the android:setFocusable from the Button widget, this tells Android that the button can receive focus.

After we created this layout, we can continue with the custom dialog class implementation. The main idea of the custom Dialog class is this : you need to set focus on a component different than the one that will get user input, you need to add a FocusChangeListener on the EditText widget (this is where we will force the keyboard to pop up) and after you added the focus listener you need to request focus on the widget. To improve user experience you will also need to hide the keyboard when the dialog is closed, for this you will need a reference to your dialog’s root layout and you need to add a GlobalLayoutListener.
Let’s take a closer look at the code, you can add the following snippets either in your constructor or in the onCreate method.

We start with the button, because we need it to have focus before the EditText.

this.okBtn = (Button) findViewById(R.id.button1);
this.okBtn.setOnClickListener(this);
this.okBtn.requestFocus();

Notice the this.okBtn.requestFocus(), this will get the focus to the button. I also implemented the onClick listener that will just dismiss the dialog because I don’t care about a result in this demo project. Moving on to the EditText widget this is what we need :

this.textBox = (EditText) findViewById(R.id.editText1);
this.textBox.setOnFocusChangeListener(new OnFocusChangeListener() {
 
	@Override
	public void onFocusChange(View arg0, boolean arg1) {
		InputMethodManager inputMgr = (InputMethodManager)getContext().
                                                 getSystemService(Context.INPUT_METHOD_SERVICE);
		inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED,
                                         InputMethodManager.HIDE_IMPLICIT_ONLY);
			}
		});
		this.textBox.requestFocus();
		this.keyboardVisible = true;

I use the toggleSoftInput method to show/hide the keyboard because the alternative (showSoftInput() / hideSoftInputFromWindow()) didn’t work for me, it could also cause troubles if you have more than one widgets that take user input. You can see we request focus for the EditText immediately after setting the listener, this will ensure that the widget will be focused and the soft-input will be shown. Also notice the boolean variable assignment this.keyboardVisible = true, this will be important later on.
Now you have a dialog window that will automatically show the soft-input keyboard. In order to hide the keyboard when the dialog closes you will also need to add the following code :

LinearLayout rootLayout = (LinearLayout) findViewById(R.id.dlgRoot);
rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 
			@Override
			public void onGlobalLayout() {
				keyboardVisible = !keyboardVisible;
			}
		});

The root layout of your dialog comes in to play and will handle the GLobalLayout events. The GlobalLayout event is triggered when the layout is changing because of a global event (for example adjusting the layout size when a soft-input keyboard is shown/hidden). The only thing we need to do here is toggle the value of keyboardVisible variable, this will in turn influence the behavior of the
onStop method, basically telling it if it needs to call the toggleSoftInput method.

@Override
protected void onStop() {
	super.onStop();
	if (keyboardVisible) {
		InputMethodManager inputMgr = (InputMethodManager) getContext().
				getSystemService(Context.INPUT_METHOD_SERVICE);
		inputMgr.toggleSoftInput(0, 0);
		}
	}

Before you hide the keyboard you need to make sure it’s visible,otherwise instead of hiding you will be showing the keyboard. The alternate method hideSoftInputFromWindow() would have fixed this problem, but I couldn’t get it to work (after my EditText widget loses focus, the bind to the keyboard is lost for the current context). That was it for the custom dialog implementation, let’s also take a look at the main activity that will show this dialog.

The main activity
This is pretty much an ordinary Activity and I only want to point out 2 issues :

  • always create your dialogs in the onCreateDialog method, it saves you some trouble and assures you that the dialog will be handled correctly if the user changes phone orientation.
    @Override
    protected Dialog onCreateDialog(int id) {
    	switch (id) {
    	case DLG_ID:
    		MyCustomDialog dlg = new MyCustomDialog(this);
    		dlg.setOnDismissListener(this);
    		return dlg;
    		}
    	return null;
    }
  • be aware that activities cache the dialogs, you can find yourself searching for nonexistent bugs for hours (learned it the hard way). My solution is to add a dismiss listener to the dialog , do whatever I need to do with the result of the dialog and then remove it from the activity, this ensures that a new dialog will be created every time.
    @Override
    public void onDismiss(DialogInterface arg0) {
    	removeDialog(DLG_ID);
    }

    That was all, you now have a dialog that will automatically pop-up a keyboard when it’s shown.
    Thanks for reading, I know it’s not the cleanest solution but at least it works, as promised at the begining of the article here is the demo project .

    Finally, there’s another very important peculiarity of what does Cialis that brings it so high above its alternatives. It is the only med that is available in two versions – one intended for use on as-needed basis and one intended for daily use. As you might know, Viagra and Levitra only come in the latter of these two forms and should be consumed shortly before expected sexual activity to ensure best effect. Daily Cialis, in its turn, contains low doses of Tadalafil, which allows to build its concentration up in your system gradually over time and maintain it on acceptable levels, which, consequently, makes it possible for you to enjoy sex at any moment without having to time it.

By continuing to use the site, you agree to the use of cookies. More information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close