You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RecyclerView中点击HeaderViewHolder的按钮从第一项滚动到第二项

问题解决方法

问题根因

你遇到的第一次点击无法滚动到位的问题主要有两个原因:

  • onBindViewHolder 入参的position是ViewHolder绑定时的静态值,点击时如果列表位置发生过变化,该值会不准确。
  • RecyclerView原生的smoothScrollToPosition逻辑是只要目标item进入可视区域就停止滚动,若第二个item初始已有部分露出在屏幕中,第一次调用只会滚动到它刚好完全可见,不会对齐到RecyclerView顶部,第二次点击才会触发完整滚动。

修复方案

步骤1:修改点击事件的位置获取逻辑,改用点击时的实时位置

步骤2:自定义SmoothScroller实现目标item顶部对齐RecyclerView的效果

完整实现代码如下:

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    if (holder.itemViewType == HEADER_ITEM) {
        val viewHolder = holder as HeaderViewHolder
        viewHolder.btn_next.setOnClickListener {
            // 取点击时的实时位置,避免绑定后位置变化导致错误
            val currentPos = holder.bindingAdapterPosition
            if (currentPos != RecyclerView.NO_POSITION) {
                scrollToItemTop(mRecyclerView, currentPos + 1)
            }
        }
    } else {
        val viewHolder = holder as DefaultViewHolder
    }
}

/**
 * 滚动到目标位置,且目标item顶部与RecyclerView顶部对齐
 */
private fun scrollToItemTop(recyclerView: RecyclerView, targetPos: Int) {
    val layoutManager = recyclerView.layoutManager as? LinearLayoutManager ?: return
    val smoothScroller = object : LinearSmoothScroller(recyclerView.context) {
        override fun getVerticalSnapPreference(): Int = SNAP_TO_START
        // 如果是横向滚动,替换为下面的方法
        // override fun getHorizontalSnapPreference(): Int = SNAP_TO_START
    }
    smoothScroller.targetPosition = targetPos
    layoutManager.startSmoothScroll(smoothScroller)
}

内容的提问来源于stack exchange,提问作者Maksimka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 09:18:03