Reputation: 12659
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?
Upvotes: 11
Views: 12533
Reputation: 89
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
val window = getDialog()?.window
if (window != null) {
WindowCompat.getInsetsController(window, window.decorView).hide(WindowInsetsCompat.Type.ime())
}
}
Upvotes: 0
Reputation: 483
found a simple way to hide dialog keyboard
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)
}
}
Upvotes: 1
Reputation: 417
In my case I was using:
android:windowSoftInputMode="adjustPan|stateVisible"
I deleted stateVisible
:
android:windowSoftInputMode="adjustPan"
And onDismiss()
, no need to call hideSoftInput
method.
Upvotes: 2
Reputation: 2804
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());
}
});
Upvotes: 1
Reputation: 958
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
Upvotes: 14
Reputation: 123
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);
}
}
});
Upvotes: 1
Reputation: 81
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);
}
}
Upvotes: 8
Reputation: 12659
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
Upvotes: 21