android

android-edittext

android-softkeyboard

keyboard

focus

I want to automatically show the soft-keyboard when an EditText is focused (if the device does not have a physical keyboard) and I have two problems:

  1. When my Activity is displayed, my EditText is focused but the keyboard is not displayed, I need to click again on it to show the keyboard (it should be displayed when my Activity is displayed).

  2. And when I click done on the keyboard, the keyboard is dissmissed but the EditText stays focused and y don't want (because my edit is done).

To resume, my problem is to have something more like on the iPhone: which keep the keyboard sync with my EditText state (focused / not focused) and of course does not present a soft-keyboard if there is a physical one.

Solution 1

To force the soft keyboard to appear, you can use

EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
yourEditText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);

And for removing the focus on EditText, sadly you need to have a dummy View to grab focus.


To close it you can use

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);

This works for using it in a dialog

public void showKeyboard(){
    InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

public void closeKeyboard(){
    InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}

Solution 2

I had the same problem. Immediately after editText VISIBILITY change from GONE to VISIBLE, I had to set the focus and display the soft keyboard. I achieved this using the following code:

new Handler().postDelayed(new Runnable() {
            
    public void run() {
//        ((EditText) findViewById(R.id.et_find)).requestFocus();
//              
        EditText yourEditText= (EditText) findViewById(R.id.et_find);
//        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
//        imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);

        yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0f, 0f, 0));
        yourEditText.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0f, 0f, 0));                          
    }
}, 200);

It works for me with 100ms delay, but failed without any delay or with only a delay of 1ms.

Commented part of code shows another approach, which works only on some devices. I tested on OS versions 2.2 (emulator), 2.2.1 (real device) and 1.6 (emulator).

This approach saved me a lot of pain.

Solution 3

To cause the keyboard to appear, use

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

This method is more reliable than invoking the InputMethodManager directly.

To close it, use

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

Solution 4

When nothing else works, force it to be shown:

editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

And then later, if you wish to close it, in onPause() for example, you can call:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

Solution 5

The following code is pillaged from the Google's 4.1 source code for SearchView. Seems to work, fine on lesser versions of Android as well.

private Runnable mShowImeRunnable = new Runnable() {
    public void run() {
        InputMethodManager imm = (InputMethodManager) getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        if (imm != null) {
            imm.showSoftInput(editText, 0);
        }
    }
};

private void setImeVisibility(final boolean visible) {
    if (visible) {
        post(mShowImeRunnable);
    } else {
        removeCallbacks(mShowImeRunnable);
        InputMethodManager imm = (InputMethodManager) getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindowToken(), 0);
        }
    }
}

Then in addition, the following code needs to be added as the Control/Activity is created. (In my case it's a composite control, rather than an activity).

this.editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    public void onFocusChange(View v, boolean hasFocus) {
        setImeVisibility(hasFocus);
    }
});

Solution 6

android:windowSoftInputMode="stateAlwaysVisible" -> in manifest File.

edittext.requestFocus(); -> in code.

This will open soft keyboard on which edit-text has request focus as activity appears.

Solution 7

I have had some recent luck in some simple cases with the code below. I haven't finished all testing but....

EditText input = (EditText) findViewById(R.id.Input);
input.requestFocus();    
input.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0f, 0f, 0));
input.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0f, 0f, 0));

And presto the keyboard shows up.

Solution 8

You can try to force the soft keyboard to appear, it works for me:

...
dialog.show();
input.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

Solution 9

And for Kotlin just use this extensions:

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

fun EditText.hideKeyboard() {
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(this.windowToken, 0)
}

Solution 10

Sometimes raukodraug's answer won't work. I've make it in this way with some trials and errors:

public static void showKeyboard(Activity activity) {
    if (activity != null) {
        activity.getWindow()
                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }
}

public static void hideKeyboard(Activity activity) {
    if (activity != null) {
        activity.getWindow()
                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }
}

And the EditText part:

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                hideKeyboard(getActivity());
            } else {
                showKeyboard(getActivity());
            }
        }
    });

Solution 11

showSoftInput was not working for me at all.

I figured I needed to set the input mode: (here in the Activity component in the manifest)

android:windowSoftInputMode="stateVisible" 

Solution 12

To hide keyboard, use this one:

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

and to show keyboard:

getActivity().getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

Solution 13

For fragment, sure its working:

 displayName = (EditText) view.findViewById(R.id.displayName);
    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

Solution 14

Kotlin extension for showing the keyboard on focus.

This is a combination of previous responses, which where either too long or incomplete.

This extension posts a runnable on the message queue which shows the soft keyboard after requesting focus:

fun View.showSoftKeyboard() {
    post {
        if (this.requestFocus()) {
            val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
        }
    }
}

Call it from any view when needed afterwards:

editText.showSoftKeyboard()

Solution 15

Believe or not my problem with Soft Keyboard was resolved when I discovered that the Activities animations can disable the Soft Keyboard. When you call the intent with the

i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);

and

overridePendingTransition(0, 0);

It can hide the Soft Keyboard and there isn't a way to show it.

Solution 16

I had the same problem in various different situations, and the solutions i have found work in some but dont work in others so here is a combine solution that works in most situations i have found:

public static void showVirtualKeyboard(Context context, final View view) {
    if (context != null) {
        final InputMethodManager imm =  (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        view.clearFocus();

        if(view.isShown()) {
            imm.showSoftInput(view, 0);
            view.requestFocus();
        } else {
            view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                @Override
                public void onViewAttachedToWindow(View v) {
                    view.post(new Runnable() {
                        @Override
                        public void run() {
                            view.requestFocus();
                            imm.showSoftInput(view, 0);
                        }
                    });

                    view.removeOnAttachStateChangeListener(this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                    view.removeOnAttachStateChangeListener(this);
                }
            });
        }
    }
}

Solution 17

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

Solution 18

I combined everything here and for me it works:

public static void showKeyboardWithFocus(View v, Activity a) {
    try {
        v.requestFocus();
        InputMethodManager imm = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
        a.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Solution 19

It worked for me. You can try with this also to show the keyboard:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

Solution 20

Simply add this line in your EditText view:

android:isScrollContainer="true"

and TADA - keyboard began to show up automatically!

I had similar problem and discovered this simple and strange solution.

As already was mentioned here by user3392439, appearance of the keyboard upon focus somehow wierdly connected with presense of the scroll component in the XML file.

Even presence of another EditText view which comprises abovementioned line in same XML makes keyboard appear no matter which one of EditTexts is currently focused.

If you have at least one visible view comprising scroll component in your XML file - keyboard will appear automatically on focus.

If no scroll - then you need to click on EditText to make keyboard appear.

Solution 21

code snippet . . .

public void hideKeyboard(Context activityContext){

    InputMethodManager imm = (InputMethodManager)
            activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);

    //android.R.id.content ( http://stackoverflow.com/a/12887919/2077479 )
    View rootView = ((Activity) activityContext)
            .findViewById(android.R.id.content).getRootView();

    imm.hideSoftInputFromWindow(rootView.getWindowToken(), 0);
}

public void showKeyboard(Context activityContext, final EditText editText){

    final InputMethodManager imm = (InputMethodManager)
            activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);

    if (!editText.hasFocus()) {
        editText.requestFocus();
    }

    editText.post(new Runnable() {
        @Override
        public void run() {
            imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
        }
    });
}

Solution 22

Inside your manifest:

android:windowSoftInputMode="stateAlwaysVisible" - initially launched keyboard. android:windowSoftInputMode="stateAlwaysHidden" - initially hidden keyboard.

I like to use also "adjustPan" because when the keyboard launches then the screen auto adjusts.

 <activity
      android:name="YourActivity"
      android:windowSoftInputMode="stateAlwaysHidden|adjustPan"/>

Solution 23

just add android:windowSoftInputMode="stateHidden" in manifest file...

Solution 24

final InputMethodManager keyboard = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

Solution 25

None of the Answers worked for me. Here is a simple way.

searchEditText.setVisibility(View.VISIBLE);
                final Handler handler=new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        searchEditText.requestFocus();
                    }
                }, 400);

Just delayed the requestFocus() method for 400ms.

Solution 26

All solutions given above (InputMethodManager interaction in OnFocusChangeListener.onFocusChange listener attached to your EditText works fine if you have single edit in the activity.

In my case I have two edits.

 private EditText tvX, tvY;
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 tvX.setOnFocusChangeListener(this);
    tvY.setOnFocusChangeListener(this);

@Override
public void onFocusChange(View v, boolean hasFocus) {       
    InputMethodManager imm =  (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(tvX.hasFocus() || tvY.hasFocus()) {            
        imm.showSoftInput(v, 0);            
    } else {
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);         
    }       
};

I have observed that onFocusChange is triggered for tvX with hasFocus=true (keyboard shown) but then for tvY with hasFocus=true (keyboard hidden). In the end, no keyboard was visible.

General solution should have correct statement in if "show keyboard if EditText text has focus"

Solution 27

In your onResume() section of the Activity you can do call the method bringKeyboard();

 onResume() {
     EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
     bringKeyboard(yourEditText);
 }


  protected boolean bringKeyboard(EditText view) {
    if (view == null) {
        return false;
    }
    try {
      // Depending if edittext has some pre-filled values you can decide whether to bring up soft keyboard or not
        String value = view.getText().toString();
        if (value == null) {
            InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
            return true;
        }
    } catch (Exception e) {
        Log.e(TAG, "decideFocus. Exception", e);
    }
    return false;
  }

Solution 28

As I read on the official document, I think this is the best answer, just pass the View to parameter such as your EditText, but showSoftKeyboard seems like not working on landscape

private fun showSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
    }
}

private fun closeSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }
}

Solution 29

For Kotlin:

val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

fun showKeyboard() {
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
    }

fun hideKeyboard() {
        imm.hideSoftInputFromWindow(phoneNoInputTxt.windowToken, 0);
    }

Then just call what you want!

Solution 30

Here's a more reliable solution i got from Square:

fun View.focusAndShowKeyboard() {
   /**
    * This is to be called when the window already has focus.
    */
   fun View.showTheKeyboardNow() {
       if (isFocused) {
           post {
               // We still post the call, just in case we are being notified of the windows focus
               // but InputMethodManager didn't get properly setup yet.
               val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
               imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
           }
       }
   }

   requestFocus()
   if (hasWindowFocus()) {
       // No need to wait for the window to get focus.
       showTheKeyboardNow()
   } else {
       // We need to wait until the window gets focus.
       viewTreeObserver.addOnWindowFocusChangeListener(
           object : ViewTreeObserver.OnWindowFocusChangeListener {
               override fun onWindowFocusChanged(hasFocus: Boolean) {
                   // This notification will arrive just before the InputMethodManager gets set up.
                   if (hasFocus) {
                       this@focusAndShowKeyboard.showTheKeyboardNow()
                       // Its very important to remove this listener once we are done.
                       viewTreeObserver.removeOnWindowFocusChangeListener(this)
                   }
               }
           })
   }
}

Code credits from here.