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

Kotlin实现横向RecyclerView轮播吸附后如何从Adapter返回位置到MainActivity

解决方案

你当前无法收到位置回调的核心原因有两个:

  1. 自定义的OnItemClickListener仅做了声明和绑定,没有在Adapter中触发调用逻辑
  2. 滚动停止后的吸附位置不需要通过Adapter获取,直接结合SnapHelper和RecyclerView滚动监听获取更合理

修改步骤

1. 新增滚动停止监听(MainActivity.kt)

在onCreate中添加RecyclerView滚动状态监听,滚动停止时通过SnapHelper获取对齐的选中位置:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    item_list.initialize(itemAdapter)
    itemAdapter.setOnItemClickListener(this)
    // 先实例化SnapHelper保存引用
    val snapHelper = ItemSnapHelper()
    snapHelper.attachToRecyclerView(item_list)
    item_list.setViewsToChangeColor(listOf(R.id.list_item_background, R.id.list_item_text))
    item_list.scrollToPosition(Int.MAX_VALUE/2)
    itemAdapter.setItems(possibleItems)

    // 新增滚动停止监听
    item_list.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            // 仅在滚动停止时获取位置
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                val snapView = snapHelper.findSnapView(recyclerView.layoutManager)
                snapView?.let { view ->
                    val layoutPosition = recyclerView.getChildAdapterPosition(view)
                    // 取模得到真实位置(适配无限轮播逻辑)
                    val realPosition = layoutPosition % possibleItems.size
                    // 此处可直接使用拿到的真实位置
                    Toast.makeText(this@MainActivity, "当前选中位置:$realPosition", Toast.LENGTH_SHORT).show()
                }
            }
        }
    })
}

2. 补充点击事件回调逻辑(可选,若需要item点击回调)

如果需要保留item点击回调,修改ItemAdapter.kt中onBindViewHolder和ItemViewHolder的bind方法,触发回调:

// ItemAdapter.kt onBindViewHolder修改
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
    if (items.isEmpty()) return
    val pos = position % items.size
    val currentItem = items[pos]
    holder.bind(currentItem, pos, itemClick, listener)
}

// ItemViewHolder的bind方法修改
class ItemViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
    fun bind(item: Item, realPosition: Int, itemClick: (position:Int,item:Item) -> Unit, listener: ItemAdapter.OnItemClickListener) {
        view.list_item_text.text = item.title
        view.list_item_icon.setImageResource(item.icon)
        // 触发点击回调
        view.setOnClickListener {
            itemClick.invoke(realPosition, item)
            listener.getAdapterPosition(realPosition)
        }
    }
}

实现效果

效果示意图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:15:01