EditText获焦时点击外部隐藏软键盘失效问题求助
解决ScrollView嵌套下点击外部隐藏软键盘失效的问题
问题原因
当布局嵌套ScrollView时,ScrollView会拦截并消费触摸事件,导致Activity的onTouchEvent无法接收到点击事件,因此原有逻辑失效。
可行解决方案
方案1:自定义ScrollView处理触摸事件
重写ScrollView的onTouchEvent方法,在触摸事件中判断点击区域是否在EditText外,若是则隐藏软键盘:
class CustomScrollView(context: Context, attrs: AttributeSet?) : ScrollView(context, attrs) { override fun onTouchEvent(event: MotionEvent): Boolean { if (event.action == MotionEvent.ACTION_DOWN) { val activity = context as Activity val currentFocus = activity.currentFocus if (currentFocus is EditText) { val outRect = Rect() currentFocus.getGlobalVisibleRect(outRect) // 判断点击位置是否在EditText区域外 if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { currentFocus.clearFocus() val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(currentFocus.windowToken, 0) } } } // 保留ScrollView的原生滚动逻辑 return super.onTouchEvent(event) } }
将布局中的原生ScrollView替换为自定义的CustomScrollView即可。
方案2:在Activity的dispatchTouchEvent中处理
dispatchTouchEvent是触摸事件分发的起点,不受子View拦截影响,直接在这里判断处理:
override fun dispatchTouchEvent(ev: MotionEvent): Boolean { if (ev.action == MotionEvent.ACTION_DOWN) { val currentFocus = currentFocus if (currentFocus is EditText) { val outRect = Rect() currentFocus.getGlobalVisibleRect(outRect) if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) { currentFocus.clearFocus() val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(currentFocus.windowToken, 0) } } } return super.dispatchTouchEvent(ev) }
替换原有Activity中重写的onTouchEvent方法即可,无需修改布局结构。
方案3:给ScrollView设置触摸监听器
在Fragment中给ScrollView添加OnTouchListener,逻辑与自定义ScrollView一致:
scrollView.setOnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { val activity = requireActivity() val currentFocus = activity.currentFocus if (currentFocus is EditText) { val outRect = Rect() currentFocus.getGlobalVisibleRect(outRect) if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) { currentFocus.clearFocus() val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(currentFocus.windowToken, 0) } } } // 传递事件给ScrollView,保证滚动功能正常 v.onTouchEvent(event) }
内容的提问来源于stack exchange,提问作者wish
相关产品推荐
相关产品推荐

