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

RecyclerView中viewHolder.adapterPosition返回错误值求助

RecyclerView左滑删除位置错乱问题解决方案

你的问题核心在于在onSwiped中过早调用notifyDataSetChanged(),导致ViewHolder的位置信息失效,再加上延迟获取位置的操作,进一步加剧了位置错乱的问题。另外,错误的通知方式也会影响RecyclerView的状态管理。

1. 修正滑动删除核心逻辑

不要在滑动回调中立刻刷新整个列表,先获取有效位置,处理数据后用精准的通知方法更新RecyclerView:

val swipeSchedule = object : SwipeSchedule(this) {
    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        val position = viewHolder.adapterPosition
        // 确保位置有效(ViewHolder未被回收)
        if (position != RecyclerView.NO_POSITION) {
            // 删除列表中对应数据
            schedulesList.removeAt(position)
            // 精准通知RecyclerView移除该项,避免全量刷新
            adapter.notifyItemRemoved(position)
            // 更新SharedPreferences中的数据
            val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
            val editor = sharedPreferences.edit()
            val gson = Gson()
            val json = gson.toJson(schedulesList)
            editor.putString("schedules", json)
            editor.apply()
            
            toast("已删除项目")
        }
    }
}
val touchHelper = ItemTouchHelper(swipeSchedule)
touchHelper.attachToRecyclerView(binding.selectDeviceList)

2. 优化添加项目的通知方式

添加项目时,notifyDataSetChanged()会强制刷新所有项,改用notifyItemInserted更高效,也能避免潜在的位置同步问题:

binding.addSchedule.setOnClickListener {
    var schName = "0"
    var schId = 0
    if(schedulesList.isNotEmpty()) {
        schName = schedulesList[schedulesList.lastIndex].scheduleName
        schId = schedulesList[schedulesList.lastIndex].scheduleId + 1
    }
    val newItem = SchedulesRVModal(schName, schId)
    schedulesList.add(newItem)
    // 仅通知新增项的位置,而非全量刷新
    adapter.notifyItemInserted(schedulesList.lastIndex)

    val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
    val editor = sharedPreferences.edit()
    val gson = Gson()
    val json = gson.toJson(schedulesList)
    editor.putString("schedules", json)
    editor.apply()
}

3. 移除不必要的冗余操作

原代码中的runBlocking和Handler.postDelayed完全多余:

  • runBlocking会阻塞UI线程,导致卡顿
  • 延迟获取位置时,ViewHolder可能已经被RecyclerView回收,返回的位置自然错误

为什么另一处RecyclerView功能正常?

大概率是另一处代码没有在滑动回调中调用notifyDataSetChanged(),而是先处理数据,再用notifyItemRemoved这类精准通知方法,因此ViewHolder的位置信息能保持有效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:18:27