NestedScrollView(RecyclerView)与EditText滑动冲突
NestedScrollView(RecyclerView)
可滑动,但嵌套的 EditText
不可滑动。
原因分析
NestedScrollView(RecyclerView)
把事件消费掉了,没有传递到EditText
,从而导致没法使得 EditText
响应事件
解决思路
解决滑动冲突不难,核心思想就是要根据滑动的方向以及业务的场景来判断此时应该由哪个View处理滑动事件。
- 内部拦截法,当满足操作的时候,就通知父view不要拦截,其他情况,正常走父view的滑动。
- 当触摸的是
EditText
& 当前EditText
多行可滚动时,则将事件交给EditText
处理,即进行滚动 - 否则将事件交由其父类处理,即交给
NestedScrollView(RecyclerView)
进行滚动。
解决方案
复写EditText
的onTouch()
并 采用 requestDisallowInterceptTouchEvent(true)
进行触碰事件拦截。
@SuppressLint("ClickableViewAccessibility")
private val onTouchListener = OnTouchListener { v, event ->
// 当触摸的是EditText & 当前EditText可滚动时,则将事件交给EditText处理
val canVerticalScroll = viewBinding.etFeedback.lineCount > viewBinding.etFeedback.maxLines
if (v.id == R.id.etFeedback && canVerticalScroll) {
v.parent.requestDisallowInterceptTouchEvent(true)
// 否则将事件交由其父类处理
if (event.action == MotionEvent.ACTION_UP) {
v.parent.requestDisallowInterceptTouchEvent(false)
}
}
false
}
NestedScrollView与RecyclerView滑动冲突
NestedScrollView
可滑动,但嵌套的 RecyclerView
不可滑动。
解决思路
- 当触摸的是
RecyclerView
& 当前RecyclerView
可滚动时,则将事件交给RecyclerView
处理,即进行滚动 - 否则将事件交由其父类处理,即交给
NestedScrollView
进行滚动。
解决方案
复写RecyclerView
的onTouch()
并 采用 requestDisallowInterceptTouchEvent(true)
进行触碰事件拦截。
// 解决NestedScrollView RecycleView 嵌套 滑动冲突,RecycleView内容展示不全 问题
binding.rv.setOnTouchListener { v, event ->
// RecyclerView & 当前RecyclerView可滚动时,则将事件交给RecyclerView处理
val itemCount = binding.rv.adapter?.itemCount ?: 0
val canScroll = itemCount > binding.rv.childCount
if (v.id == R.id.rv && canScroll) {
v.parent.requestDisallowInterceptTouchEvent(true)
// 否则将事件交由其父类处理
if (event.action == MotionEvent.ACTION_UP) {
v.parent.requestDisallowInterceptTouchEvent(false)
}
}
false
}