ChatGPT解决这个技术问题 Extra ChatGPT

How to show soft-keyboard when edittext is focused

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:

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). 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.

I just have a basic EditText like: And on my activity I have this: EditText editTxt = (EditText) findViewById(R.id.myEditText); editTxt.requestFocus();
This helped me better than any answer in this post : stackoverflow.com/a/2418314/1491212

r
raukodraug

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

If I do this, the soft-keyboard is shown when the activity appears (it's good) but when my focus leave the EditText and go to a Button for example, the keyboard stays (that's bad).
Doesn't work for me with an EditText in a dialog which already has focus. Not sure why.
@AbdellahBenhammou, perhaps doing a requestFocus call onn your edit text before showing the soft input might solve your issue. It did for me.
@AbdellahBenhammou, do this in your DialogFragment's onCreate(): getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
Worked only in conjunction with yourEditText.requestFocus() as described here: stackoverflow.com/questions/8991522/…
L
Leonid Ustenko

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.


That's genius, Mike. A twisted genius, perhaps, but "works for me."
I didn't know something could be so ugly and so beautiful at the same time. Thank you so much!
@jellyfish this simulates a tap on the EditText. For others reading this, instead of creating a new Handler you could also use the View.postDelayed() method on the yourEditText widget itself.
This is a hack - much better solution by David Chandler.
If David Chandler's solution works across all Android versions/devices and for the case when VISIBILITY was just changed from GONE to VISIBLE, then YES - you should use his solution instead.
C
Community

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

Can somebody please explain why this is more reliable than directly invoking InputMethodManager? (For one, it doesn't work, unlike raukodraug's solution.)
Does not work for me either. Working in Android 2.3.5. raukodraug's solution does work for me. Searched for version dependency but could not find one.
This worked for me in Android 4.4.2. The InputMethodManager method chosen as the solution for this post did not work for me.
after using the method in the answer i appended this and it worked,but without it it didnt work. thanx
Didn't work for me in Android 4.4.2. It shows the keyboard but didn't hide it.
B
Bolling

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

You were right, @Bolling! When nothing else worked, your code saved me. Thanks!
Your code was the only one who worked for me, and I tried every solution on this page! Thanks a lot!
dont force it. in some cases when you go from foreground to background the keyboard will remain there because you forced it. its a fragmentation issue but i've seen it on samsung duos.
I usually always have code to close the keyboard onPause() since I have seen it get stuck even if you did not force it up.
That did work, but when move to the other screens, it still remains open
T
TWiStErRob

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

Thanks! It works amazingly well. And it's the solution I'm more comfortable with from all the answers and topics I've been reading on this issue.
:-D setImeVisibility(hasFocus)?
I tried this method since I was actually "rolling my own search view" (didn't want to have to do that but there were reasons). This worked for me except for at launch of the activity. I added android:windowSoftInputMode="alwaysVisible" to the activity and already had requestFocus() being called on the edit text. Works like a champ.
After trying several variations, this was the only one that worked consistently for me (Android 4.42). Thx
+1 - regarding what the exact question is this is the most complete and correct answer and should be the accepted answer
S
Shreyos Adikari

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.


This open the keyboard at Activity creation.
doesn't answer the question, but helped me :)
opens key without requestfocus in api 22
Works fine for my case. I wonder why request focus attribute just from the xml needs a mention in the manifest as well !
L
Leonid Ustenko

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.


For my case I had a button to add some optional information. In the button.onClick handler the above code was added to force the soft keyboard to appear for the input of the optional info. Droid 2.2.2
this is a good solution but do not forget that you should create a MotionEvent object and call recycle() on them after usage, to be re-used by a later caller.
You just need one dispatchTouchEvent() with ACTION_UP as its argument..
V
Vadim Zin4uk

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

This works for me ... I had tried these InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(name, inputMethodManager.SHOW_IMPLICIT); or getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); but none of them were working.
b
bitvale

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

just what I was looking for.
X
Xieyi

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

This is the only solution that worked for me on Android 5
Q
Qantas 94 Heavy

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" 

M
Mubashar

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

For a DialogFragment, you can call this in an overridden onStart(), and you can use getDialog().getWindow() as an alternative to getActivity().getWindow().
A
Arish Khan

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

A
Alex Burdusel

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

M
Marvin Pinto

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.


n
n0sferat0k

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

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

M
Mike

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

M
Massimiliano Kraus

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

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

W
Waldmann

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.


This is very strange but it definitely works - I was attempting to requesFocus() from within a click handler and this is the only way other than an explicit showSoftInput SHOW_FORCED
Holy sh*t, thanks man. No clue why it works but I've tested it on 8 devices from different manufacturers and it worked everytime!
Thanks, @Waldmann, only your answer worked perfectly !!
Not working for me
J
Jongz Puangput

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

M
Massimiliano Kraus

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"/>

P
Prakash Gavade

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


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

toggleSoftInput is deprecated.
S
Satyajit

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.


B
Bartosz Bilicki

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"


V
Vikas

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

What's the WidgetUtils.showKeyboard? That's the most important bit here.
T
Thành Thỏ

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

J
Jamil Hasnine Tamim

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!


This answer is incomplete. InputMethodManager and the IBinder reference can't be resolved.
@MarkLapasa check again my answer, hope it will help you. Thanks.
S
Steve Kamau

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() // It’s very important to remove this listener once we are done. viewTreeObserver.removeOnWindowFocusChangeListener(this) } } }) } }

Code credits from here.


Using an observer seems like the more sensible way to handle the focus delay, but I can't make it work…
After deleting if statement inside onWindowFocusChanged worked for me. Thanks