Reputation: 11093
I have a application, and need to close the softkeyboard on a rather large amount of actions. For example, when clicking a button, when a new layout is drawn, on screen orientation change, when the controller tells the UI to, et cetera. I use the optionsMenuButton to flip view with a ViewFlipper, and obviously I want the keyboard to hide in the flipped view (there is no input field there).
I've tried these so far and tell why these aren't reliable:
This one didn't work because I have lots of editTexts, and other views. I need a more generic one, one that does not require a view as argument, if possible.
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
This one does not work at all for me:
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
This one works, but immediately pops the keyboard up again when the view is flipped.
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
This one works sometimes, but getCurrentFocus() returns null most of the time.
InputMethodManager inputManager = (InputMethodManager)
Context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
This one works only if the keyboard is shown:
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
This one does not work with the EditText like the first piece of code, but with the root Layout, which changes on orientation change and everytime the oncreate is called. I have different layout XML for landscape/portrait and normal/large. All the root Layouts have the ID root
. This works nicely the first time, but after that, it doesn't work anymore.
InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(findViewById(R.id.root).getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
Bottomline: I've tried hella lot of softkeyboard hiding methods, but none of them seems to work reliably. Is there any method for hiding the soft keyboard reliably?
Upvotes: 15
Views: 14003
Reputation: 690
Try this:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Upvotes: 0
Reputation: 33
kotlin. Put this on common BaseActivity. just call hideKeyboard() method anywhere in your activity similar apply for Fragment.
open class BaseActivity : AppCompatActivity() {
fun Fragment.hideKeyboard() {
view?.let { activity?.hideKeyboard(it) }
}
fun Context.hideKeyboard(view: View) {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
}
Upvotes: 1
Reputation: 22997
Since you need an EditText
to bring up the keyboard, find the particular one and use the first method you displayed to hide the keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
However, you will need that EditText
. First, get all views:
public static ArrayList<View> getAllViewsFromRoots(View...roots) {
ArrayList<View> result = new ArrayList<View>();
for (View root : roots) {
getAllViews(result, root);
}
return result;
}
private static void getAllViews(ArrayList<View> allviews, View parent) {
allviews.add(parent);
if (parent instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup)parent;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
getAllViews(allviews, viewGroup.getChildAt(i));
}
}
}
Then, get an EditText
which is visible.
public static EditText getEditText(View root) {
ArrayList<View> views = getAllViewsFromRoots(root);
for (View view : views) {
if (view instanceof EditText && view.getVisibility() == View.VISIBLE) {
return (EditText) view;
}
}
return null;
}
Call somewhere:
Toolkit.getEditText(((ViewParent) findViewById(android.R.id.content)).getChildAt(0));
with that, call the hiding method.
Upvotes: 8
Reputation: 1989
Only this solution worked for me:
mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
I had a dialog with input field, hiding the dialog didnt hide the keyboard on tablet.
Upvotes: 0
Reputation: 1052
I think if you handle the null case of getCurrentFocus(), you're good to go. I use the method below and it works like a charm!
/* Hide Keyboard */
public static void hideKeyboard(Activity activity){
InputMethodManager inputMethodManager = (InputMethodManager)activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
View focus = activity.getCurrentFocus();
if(focus != null)
inputMethodManager.hideSoftInputFromWindow(focus.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
Upvotes: 9
Reputation: 3348
This one works for me always:
InputMethodManager im = (InputMethodManager) getSystemService(MyActivity.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
Upvotes: 4