EditText未获得焦点时如何保持软键盘开启?高版本API适配问题
问题核心原因
- Android 9(API 28)之后系统对软键盘弹出逻辑做了限制,
showSoftInput方法仅在目标视图已成功获得焦点、且已附着到当前窗口时才会生效,低版本的调用逻辑在高版本会返回失败。 - 你使用的
scrollView.fullScroll(ScrollView.FOCUS_DOWN)方法会触发ScrollView的焦点转移逻辑,自动抢占EditText的焦点,导致软键盘被收起。 - SwitchCompat默认是可聚焦控件,点击时会抢走EditText的焦点,触发软键盘隐藏。
- 使用
SHOW_FORCED参数弹出的软键盘属于系统强制级,不会跟随页面焦点变化自动隐藏,就会出现退出Fragment弹Dialog时键盘仍显示的问题。
修复方案
1. 配置Activity软键盘适配属性
在AndroidManifest.xml中给当前页面对应的Activity添加配置,保证布局可跟随软键盘调整:
<activity android:name=".YourLoginActivity" android:windowSoftInputMode="adjustResize" />
2. 优化软键盘弹出方法,适配高版本系统
修改 setFocusAndShowKeyboard2 方法,等待视图完成布局后再弹出键盘:
fun setFocusAndShowKeyboard2(view : View, context: Context){ view.isFocusable = true view.isFocusableInTouchMode = true if (view.requestFocus()) { // 等待视图附着到窗口后再执行键盘弹出逻辑 view.post { val imm: InputMethodManager = ContextCompat.getSystemService(context, Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) } } }
3. 修改ScrollView滚动逻辑,避免抢占焦点
替换原有fullScroll调用,滚动时不触发焦点转移,滚动完成后保留EditText的焦点:
isInputClicked.observe(viewLifecycleOwner, Observer { if (it) { // 原有的CountDownTimer逻辑无实际作用,可直接删除替换为postDelayed scrollView.postDelayed({ // 直接滚动到ScrollView底部,不触发焦点转移 scrollView.smoothScrollTo(0, scrollView.getChildAt(0).measuredHeight) // 主动保留EditText的焦点,保证键盘不隐藏 et_phone_input.requestFocus() }, 200) } })
4. 配置SwitchCompat不抢占焦点
在XML布局的SwitchCompat节点添加如下属性,点击时不会抢走EditText的焦点:
<androidx.appcompat.widget.SwitchCompat android:id="@+id/switch_agreement" <!-- 保留原有属性 --> android:focusable="false" android:focusableInTouchMode="false" />
5. 处理页面销毁时自动隐藏键盘
在Fragment的onDestroyView生命周期中主动隐藏键盘,避免弹出Dialog时键盘残留:
override fun onDestroyView() { val imm = ContextCompat.getSystemService(requireContext(), InputMethodManager::class.java) imm?.hideSoftInputFromWindow(et_phone_input.windowToken, 0) super.onDestroyView() }
内容的提问来源于stack exchange,提问作者1Avalanche
相关产品推荐
相关产品推荐

