Recyclerview:监听填充点击事件
Posted
技术标签:
【中文标题】Recyclerview:监听填充点击事件【英文标题】:Recyclerview: listen to padding click events 【发布时间】:2018-04-06 10:29:55 【问题描述】:我有一个水平的RecyclerView
和leftPadding = 48dp
、topPadding = 24dp
和clipToPadding = false
。它从左侧的空白区域开始,但是当用户滚动列表时,它的项目被绘制在那个(以前是空白的)空间上。顶部空间始终为空。
此RecyclerView
位于带有foreground = selectableItemBackground
的FrameLayout 中。
我的问题来自RecyclerView
消耗并忽略左侧和顶部空格的触摸,这意味着OnClickListener
不会被触发,无论是附加到FrameLayout
还是RecyclerView
.
我已经在RecyclerView
上尝试了clickable = false
和focusable = false
,它不起作用。
我在寻找什么:
-
可滚动
RecyclerView
可点击的RecyclerView
项目
FrameLayout
RecyclerView's
空格被点击时的点击事件
(替代3)可点击RecyclerView's
空格
编辑:我创建了一个简单的项目来显示我正在谈论的问题:https://github.com/dadino/recyclerviewemptyspacestest 有 2 次提交,第一次我尝试捕获对父视图的点击,第二次我尝试捕获对 RecyclerView 本身的点击。它们都不起作用。
【问题讨论】:
显示你的代码。 你想看什么代码? 在您的 recyclerview 适配器中,您必须放置一个全局点击列表器和项目点击列表器,确保您只对项目执行此操作。邮编了解更多详情 每个项目的视图都有自己的 clickListener,而不是适配器(即不是视图,不能注册 clickListener)。问题不在于项目的点击侦听器,而是未在项目范围之外注册的点击(其 clickListener 没有管辖权)。 这是我讲的结构合理的问题,我很喜欢阅读它。 【参考方案1】:您必须创建自定义的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())
结果:
【讨论】:
像魅力一样工作。以上是关于Recyclerview:监听填充点击事件的主要内容,如果未能解决你的问题,请参考以下文章
Android教程2020 - RecyclerView响应点击
RecyclerView smoothScroll位于中心位置。安卓