Problems专题:Dialog
0x01 OnKeyDown部分机型无法监听
问题分析
监听返回键和音量键,重载OnKeyDown()方法,部分机型会失效。
解决方案
给相应的Dialog监听setOnKeyListener()。
1 2 3 4 5 6 7 8 9 10
| setOnKeyListener { dialog, keyCode, event -> Log.d(TAG, "setOnKeyListener: keyCode = $keyCode, event = $event") if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { handleKeyEvent(keyCode) true } else { false } }
|
注意区分keycode,防止业务层重复处理
0x02 DialogFragment不能自动弹出软键盘
方案一:延迟弹出软键盘
在dialog显示之后,延迟200ms再显示软键盘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public static void toggleKeyboard(final EditText editText, final boolean status) { if (editText == null) return; Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { InputMethodManager m = (InputMethodManager) ApplicationExtKt.getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (status) { m.showSoftInput(editText, InputMethodManager.SHOW_FORCED); } else { IBinder windowToken = editText.getWindowToken(); if (windowToken != null) { m.hideSoftInputFromWindow(windowToken, 0); } } } }, status ? 200 : 100); }
|
方案二:设置 SoftInputMode 为 SOFT_INPUT_STATE_ALWAYS_VISIBLE
1 2
| getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); inputEditText.requestFocus();
|
0x03 关闭DialogFragment无法关闭软键盘
问题分析
一般情况下,在onPause
或者dismiss
方法直接调用hideKeyboard
就可以
1 2 3 4
| override fun onPause() { KeyBoardUtils.hideKeyboard(binding.etSearch) super.onPause() }
|
但是,在某些时候还是会存在关闭不成功的情况。这是由于Dialog下面的Activity或Fragment存在EditText等抢占焦点,导致在DialogFragment在调用dismiss方法时,键盘已经被抢占焦点,所以无法关闭。
解决方案
在DialogFragment的dismiss方法回调
1 2 3 4
| override fun onDismiss(dialog: DialogInterface) { listener?.onDialogDismiss() super.onDismiss(dialog) }
|
在前一个Activity或者Fragment中重新关闭键盘。
1 2 3 4 5 6 7
| private fun onDialogDismiss() { Handler().postDelayed({ KeyBoardUtils.hideKeyboard(binding.root) }, 200) }
|