Reputation: 3089
I have code like the following to immediately show the soft keyboard when entering my app:
@Override
protected void onResume() {
super.onResume();
...
myEditText.requestFocus();
myEditText.postDelayed(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
}, 100);
...
}
However, on the Android 2.1 emulator, the keyboard appears and then immediately disappears. If I make the delay longer, like 1000, it reliably appears. On an Android 4.0 emulator, a delay of 100 reliably shows the keyboard, but shorter delays do not.
Does anyone know who might be hiding the keyboard? Is there a reliable way to prevent it? If not, is there a delay I can use to guarantee that the keyboard will show?
Upvotes: 11
Views: 6143
Reputation: 4349
put this code in onRun() in onResume() method:
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
[Edit]
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
text.requestFocus();
text.postDelayed(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(text, InputMethodManager.SHOW_FORCED);
}
}, 100);
text.postDelayed(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(text.getWindowToken(), 0);
}
}, 200);
}
Upvotes: 0
Reputation: 958
I think what you are seeing is Android identifying the view that should get focus by default and giving it focus (which hides your keyboard). Setting your delay longer or shorter just makes it so your code runs before or after that focus is set. You could figure out what view is getting focus by default, and if you don't want it to ever have focus, set it as focusable false and focusableInTouchMode false. If it does need to have focus at some point, you could set an onFocusChanged listener, and when it gets focus the first time, post your runnable(without delay) to give the focus to the EditText and open the keyboard.
Upvotes: 5
Reputation: 14059
If I understand you correctly, I think you can remove the following code in your onResume()
:
myEditText.postDelayed(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
}, 100);
And simply use android:windowSoftInputMode="stateAlwaysVisible"
for your Activity in the manifest.
Upvotes: 6
Reputation: 3089
Thanks to @Daniel Smith and @Cookster.
This was happening because I did not set a windowSoftInputMode in my manifest, so it was using the default value (stateUnspecified), which hid the keyboard on startup. Apparently, that setting is applied after some delay on resume, and so my call to show the keyboard only worked if my delay was longer than the built-in delay to hide it.
To fix, I set windowSoftInputMode="stateUnchanged" and then I always either hide or show the keyboard in onResume. I also removed the delay, which was no longer necessary once the built-in hiding was not happening.
Never mind, that mitigated the problem (it lets me reduce the delay), but it didn't fix it completely. There is something very nondeterministic about this, and the keyboard is no longer appearing if I don't use the delay. However, if I reintroduce a delay of about 100ms, the keyboard seems to show up about 90% of the time, which puts me back where I started: why is this happening and what's a safe delay?
Upvotes: 1