Recyclerview:收听填充点击事件

我有一个水平的RecyclerView其中leftPadding = 48dptopPadding = 24dpclipToPadding = false 。 它从左侧的空白区域开始,但是当用户滚动列表时,其项目将在该(先前为空)空间上绘制。 顶部空间始终为空。

在此处输入图像描述

RecyclerView位于FrameLayout内,其foreground = selectableItemBackground

我的问题来自于RecyclerView消耗并忽略左侧和顶部空间的触摸,这意味着当连接到FrameLayoutRecyclerView时,不会触发OnClickListener

我已经在RecyclerView上尝试使用clickable = falsefocusable = false ,但它不起作用。

我在找什么:

  1. 可滚动的RecyclerView 在此处输入图像描述
  2. 可点击的RecyclerView项目 在此处输入图像描述
  3. 单击RecyclerView's空白空间时, FrameLayout单击事件
  4. (替代3)可点击的RecyclerView's空白区域 在此处输入图像描述 在此处输入图像描述

编辑:我创建了一个简单的项目,显示我正在谈论的问题: https : //github.com/dadino/recyclerviewemptyspacestest有2个提交,在第一个我试图抓住父视图的点击,在第二个我试图抓住RecyclerView本身的点击。 它们都不起作用。

您必须创建自定义的RecyclerView实现,您将在其中监听触摸事件并基于此执行过滤。

 class MyRecyclerView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : RecyclerView(context, attrs, defStyleAttr) { private var isValid = false private var x: Int = 0 private var y: Int = 0 // this will help us to understand whether the event can be considered a touch or scroll private val delta: Int = ViewConfiguration.get(getContext()).scaledTouchSlop override fun onTouchEvent(e: MotionEvent?): Boolean { val onTouchEvent = super.onTouchEvent(e) when (e?.action) { MotionEvent.ACTION_DOWN -> { // saving initial touch location x = e.rawX.toInt() y = e.rawY.toInt() isValid = true } MotionEvent.ACTION_MOVE -> { if (Math.abs(e.rawX - x) > delta || Math.abs(e.rawY - y) > delta) { // if a scroll happens - no longer consider this movement as valid // this is needed for handling scroll on the inner part of `RecyclerView` isValid = false } } MotionEvent.ACTION_UP -> { if (isValid && Math.abs(e.rawX - x) < delta && Math.abs(e.rawY - y) < delta && isInRightArea(e)) { // 1. if the movement is still valid // 2. we have actually performed a click // 3. the click is in expected rectangle // then perform click performClick() } } } return onTouchEvent } // This is needed in order to handle the edge case, when a click listener // would be fired when performing a click between the items of `RecyclerView` private fun isInRightArea(e: MotionEvent): Boolean { val r = Rect() getGlobalVisibleRect(r) r.left = paddingLeft r.top = r.top + paddingTop return !r.contains(e.rawX.toInt(), e.rawY.toInt()) } } 

结果:

在此处输入图像描述