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
相关产品推荐
相关产品推荐

