我有一个
Activity
,上面有一个 Fragment
。碎片上有一个EditText
。
显示片段后键盘就会弹出,但是我设法在清单 android:windowSoftInputMode="stateHidden" 中阻止它设置
但是,还有一个按钮,可以打开带有另一个 EditText 的对话框。
我有一种方法可以在对话框关闭时自动关闭键盘。
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);
}
});
}
这个方法并不是一个很巧妙的方法,而且有一些问题。 Dialog 的
EditText
有 inputType="numberDecimal"
。 closeInput()
似乎没有关闭键盘,只是将其更改为默认字母状态。
这是怎么回事?
就我而言,我使用的方法是:
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);
}
由于清单中的活动设置,它拒绝正常工作,如果我记得你不能设置
android:windowSoftInputMode="any_of_these"
从片段 onCreateView() 方法中,您可以执行以下操作:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
关闭对话框时会自动隐藏软键盘
在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);
}
}
就我而言,我使用的是:
android:windowSoftInputMode="adjustPan|stateVisible"
我删除了
stateVisible
:
android:windowSoftInputMode="adjustPan"
并且
onDismiss()
,无需调用hideSoftInput
方法。
就我而言,解决方案是将键盘隐藏在对话框中关闭
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);
}
}
});
在这个问题上苦苦挣扎,在查看了这里的答案后,大多数似乎确实有效。由于不希望使用类而只是使用构建器,所以答案https://stackoverflow.com/a/36422411/1815624不是一个可行的解决方案。
意识到其他人可能也有同样的问题,答案是从两者中得出的: https://stackoverflow.com/a/17393446/1815624&https://stackoverflow.com/a/32648971/1815624
因此,组合答案是从片段本身获取视图:
(有人有理由不这样做吗?)
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());
}
});
找到了隐藏对话框键盘的简单方法
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)
}
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
val window = getDialog()?.window
if (window != null) {
WindowCompat.getInsetsController(window, window.decorView).hide(WindowInsetsCompat.Type.ime())
}
}