如何在StickyRecyclerHeadersAdapter的onBindHeaderViewHolder中为TextView设置点击事件
问题原因及解决方案
常见失效原因
- StickyRecyclerHeadersAdapter库的粘性Header默认是绘制在RecyclerView上层的装饰层,触摸事件默认不会分发到Header内部的子View,只会响应整个Header的触摸回调,这是最常见的原因。
- 布局文件中
tvDate的clickable属性为false,或者父布局拦截了触摸事件。 - 点击事件触发后报错但未捕获:如果使用的Context是应用上下文,直接启动Activity会缺少
FLAG_ACTIVITY_NEW_TASK标识导致崩溃,看起来就像点击没生效。 - Header复用导致点击事件绑定冲突,没有清除旧的点击监听。
可行解决方案
方案1:使用库提供的Header触摸监听(最稳定)
移除onBindHeaderViewHolder中给tvDate设置的点击事件,在RecyclerView设置Adapter的位置添加以下触摸监听代码:
val touchListener = StickyRecyclerHeadersTouchListener(recyclerView, yourAdapter) touchListener.setOnHeaderClickListener { header, position, headerId, event -> // 如果不需要限制仅点击tvDate触发跳转,可直接删除位置判断逻辑,点击整个Header都会触发跳转 val tvDate = header.findViewById<TextView>(R.id.tv_date) val touchRect = Rect() tvDate.getGlobalVisibleRect(touchRect) if (touchRect.contains(event.rawX.toInt(), event.rawY.toInt())) { val intent = Intent(context, CalenderActivity::class.java) // 若context是应用上下文需加下面这行 // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) } } recyclerView.addOnItemTouchListener(touchListener)
方案2:调整布局+优化点击绑定
如果要保留在Adapter内绑定点击的逻辑,按以下步骤调整:
- 检查
item_timeline_header.xml中tvDate的属性,添加:
<TextView android:id="@+id/tv_date" android:clickable="true" android:focusable="false" ...其他属性/>
- 优化
onBindHeaderViewHolder中的点击绑定逻辑,先清除旧监听避免复用冲突:
override fun onBindHeaderViewHolder(holder: HeaderViewHolder, position: Int) { val timelinedAt = "12 JAN 2021" holder.itemHeaderBinding.apply { tvDate.text = timelinedAt // 先清除旧监听 tvDate.setOnClickListener(null) tvDate.setOnClickListener { val intent = Intent(context, CalenderActivity::class.java) // 若context是应用上下文需加下面这行 // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) } } }
内容的提问来源于stack exchange,提问作者ganpat malekar
相关产品推荐
相关产品推荐

