11

I have an Activity with single Fragment on it. There is one EditText on the fragment.

The keyboard is popping up as soon the fragment is shown, however I managed to block it setting in the manifest android:windowSoftInputMode="stateHidden"

However, there also is a button, which opens a dialog with another EditText.

I have a method that automatically closes the keyboard on dialog dismiss.

public static void closeInput(final View caller) { caller.post(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager) caller.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(caller.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); } }); } 

The method is not a pretty hack and there is something wrong about it. Dialog's EditText has inputType="numberDecimal". The closeInput() seems to be not closing the keyboard, only changing it to the default alphabetical state.

What is going on here?

8
  • What about at the creation of your dialog you call this method and then again when the dialog is dismissed? Commented Apr 19, 2013 at 14:05
  • why would I call closeInput on dialog creation? At the time no input is visible Commented Apr 19, 2013 at 14:08
  • Oh, I thought that might have been when the first and second keyboard appeared. Commented Apr 19, 2013 at 14:10
  • Oh, I see it now, when the dialog is dismissed the fragment is creating the second keyboard. Why not just call the method to hide your keyboard in the onResume() of your fragment? Commented Apr 19, 2013 at 14:15
  • onResume() is not beeing called after dialog dismiss Commented Apr 19, 2013 at 14:17

8 Answers 8

21

In my case I used method:

public static void closeInput(final View caller) { caller.postDelayed(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager) caller.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(caller.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } }, 100); } 

It was refusing to work properly because of activity settings in Manifest, if I recall you can't have android:windowSoftInputMode="any_of_these" set

Sign up to request clarification or add additional context in comments.

4 Comments

Regarding «if I recall you can't have android:windowSoftInputMode="any_of_these"» - I managed to get all working while having windowSoftInputMode="adjustNothing|stateAlwaysHidden" and using setSoftInputMode(SOFT_INPUT_ADJUST_PAN|SOFT_INPUT_STATE_ALWAYS_HIDDEN);
In my tests, you don't need postDelayed(runnable, 100). The 100 seems fragile. You can just use post(runnable) instead (works for me). Can anyone confirm/disprove that?
I tried many solutions and this was the only one that worked. I was able to remove the delay and it caused no issues.
"you can't have android:windowSoftInputMode set" - this was the key point for me, bizarrely removing "stateHidden" fixed keyboard not hiding!
14

From fragments onCreateView() method you can do this:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) 

It will automatically hide soft keyboard on Dismiss of Dialog

1 Comment

it will be closed if the activity is declared with android:windowSoftInputMode="adjustPan" too
8

in BaseDialog.java

protected void hideSoftKeyboard() { InputMethodManager imm = (InputMethodManager) this.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive()) { imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } } 

1 Comment

Searched for days how to do this. Tried everything in every forum, finally this closed keyboard on dialog exit. Thanks
2

In my case I was using:

android:windowSoftInputMode="adjustPan|stateVisible" 

I deleted stateVisible:

android:windowSoftInputMode="adjustPan" 

And onDismiss(), no need to call hideSoftInput method.

Comments

1

In my case, solution was to put keyboard hide in dialog dismiss

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { View view = activity.getCurrentFocus(); if (view != null) { InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } }); 

Comments

1

Struggling with this issue and after reviewing the answers here, most seem to actually work. Since it was not desired to use a class rather just a builder, the answer https://stackoverflow.com/a/36422411/1815624 is not a workable solution.

Realizing others may have this same issue, an answer is being derived from both: https://stackoverflow.com/a/17393446/1815624 & https://stackoverflow.com/a/32648971/1815624

So the combination answer is grabbing the view from the fragment itself:

(Anyone got a reason not to?)

void closeKeyboard(final View caller){ caller.post(new Runnable() { @Override public void run() { InputMethodManager imm = (InputMethodManager) caller.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(caller.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } }); } 

...

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { closeKeyboard(getView()); } }); 

Comments

1

found a simple way to hide dialog keyboard

  1. dialog.setCanceledOnTouchOutside(false)
  2. call hideKeyboardFromDialogBeforeDismiss() before dialog dismiss, may be on cancel button clicked event, shouldn't call in onDismiss or onCancelListener
    binding.cancelBtn.setOnClickListener { STSystemUtil.hideKeyboardFromDialogBeforeDismiss(dialog = dialog) binding.root.postDelayed({ dialog?.dismiss() }, 200) } 
 @JvmStatic @JvmOverloads fun getInputMethodManager(context: Context? = STInitializer.application()): InputMethodManager? { return context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? } /* * 注意: 如果 dialog 包含一个或者多个EditText, 点击外部(canceledOnTouchOutside==true)不会隐藏已经显示的输入法弹框, 且通过点击取消按钮必须先隐藏输入法弹框再延时 dismiss, 因为在 onCancel/onDismiss 中 dialog?.currentFocus?.windowToken 必然已经是 null, 且 inputMethodManager?.isActive 必然是 false * ----> canceledOnTouchOutside = false * ----> binding.cancelBtn.setOnClickListener { * STSystemUtil.hideKeyboardFromDialogBeforeDismiss(dialog) * binding.root.postDelayed({ dialog?.dismiss() }, 200) * } */ @JvmStatic @JvmOverloads fun hideKeyboardFromDialogBeforeDismiss(context: Context? = STInitializer.application(), dialog: Dialog? = null) { val inputMethodManager: InputMethodManager? = getInputMethodManager(context) if (dialog == null) { if (inputMethodManager?.isActive == true) { inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS) } } else { inputMethodManager?.hideSoftInputFromWindow(dialog.currentFocus?.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) } } 

Comments

0
override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) val window = getDialog()?.window if (window != null) { WindowCompat.getInsetsController(window, window.decorView).hide(WindowInsetsCompat.Type.ime()) } } 

1 Comment

You should add explanation to your answer to make others understand your solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.