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

RecyclerView屏幕旋转后滑动功能失效及引入LiveData后崩溃问题求解

问题解答

1. 修复屏幕旋转后滑动功能失效不需要使用LiveData

屏幕旋转后项视图类型无法更新的原因是:屏幕旋转会触发Activity/Fragment销毁重建,你之前保存在Adapter内存中的historyData列表(每个条目携带的showMenu状态)会随旧实例销毁丢失,重建时你直接从数据库读取的HistoryObject默认showMenu都为false,同时重建后的Adapter是全新实例,和之前滑动手势绑定的实例不匹配,所以就算滑动事件正常触发,也无法更新新列表的状态、切换视图类型。

2. 你当前ViewModel实现的错误点

直接导致崩溃的原因

你在MainActivity的onCreate方法中每次重建都会执行historyViewModel.setHistoryList(mutableListOf()),将ViewModel中的列表强制重置为空。屏幕旋转后Activity重建先触发这个操作,LiveData会先发射空列表,此时Fragment的观察回调用空列表创建了Adapter和滑动助手,滑动时访问索引0就会触发IndexOutOfBoundsException。

其他导致功能异常的问题

  • 你每次收到LiveData的列表更新时都会调用refreshRecyclerView重新创建Adapter、重新绑定ItemTouchHelper,这一操作完全没有必要,反复创建实例会导致状态不同步。
  • ViewModel仅存储了列表的原始数据,没有持久化每个条目的showMenu状态,每次从数据库拉取的新对象默认都为关闭菜单状态,就算用了ViewModel,旋转后滑动展开的菜单状态依然会丢失。

修复方案

  1. 删除MainActivity onCreate中清空ViewModel列表的historyViewModel.setHistoryList(mutableListOf())代码。
  2. 将Adapter和ItemTouchHelper改为Fragment的成员变量,仅在onViewCreated中初始化一次,后续LiveData收到新列表时,仅更新Adapter内部的historyData数据源,调用notifyDataSetChanged()或用DiffUtil做差分更新即可。
  3. 如果需要持久化菜单展开状态,要么将showMenu字段存入数据库,要么更新ViewModel列表时保留已有条目的showMenu状态,不要直接用数据库拉取的新对象全量覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:18:03