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

屏幕旋转时RecyclerView未恢复,onBindViewHolder未触发问题

解决RecyclerView旋转后onBindViewHolder不调用的问题

看起来你已经搞定了数据保存,但旋转后列表还是不渲染,核心问题大概率是Adapter初始化或RecyclerView配置的环节漏了步骤,我帮你梳理几个关键排查点和修复方案:

1. 给Adapter添加支持已有数据集的构造函数

你的当前构造函数里直接new ArrayList<Words>()创建空数据集,旋转重建Fragment时,新的Adapter实例根本拿不到你保存的旧数据——哪怕你在其他地方存了数据,Adapter内部的mDataSet还是空的(你说确认列表非空,可能是指保存的数据源非空,但没传递给新Adapter?)。

修改构造函数,让它可以接收恢复的数据集:

public CustomAdapter(RecyclerView recyclerView, Context context, TranslateActivityFragment fragment, ArrayList<Words> savedDataSet){
    mRecyclerView = recyclerView;
    // 优先用传入的已保存数据,没有再新建空列表
    mDataSet = savedDataSet != null ? savedDataSet : new ArrayList<>();
    mFragment = fragment;
    
    View v = LayoutInflater.from(mFragment.getActivity()).inflate(R.layout.edit_translate,null,false);
    createPopupWindow(v, mFragment.getActivity());
    setEditText(v);
}

2. 重建Fragment时,必须重新配置RecyclerView

旋转后Fragment的视图会完全重建,旧的RecyclerView实例已经失效,你得在onViewCreated或onCreateView里重新绑定:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
    mRecyclerView = view.findViewById(R.id.your_recycler_view_id);
    
    // 关键!必须重新设置LayoutManager,没有它RecyclerView不会渲染任何内容
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    
    // 从savedInstanceState恢复数据
    ArrayList<Words> restoredData = null;
    if (savedInstanceState != null) {
        restoredData = savedInstanceState.getParcelableArrayList("words_data");
    }
    
    // 创建Adapter时传入恢复的数据
    mAdapter = new CustomAdapter(mRecyclerView, getContext(), this, restoredData);
    mRecyclerView.setAdapter(mAdapter);
    
    return view;
}

3. 确保数据恢复后触发Adapter更新

如果你的恢复逻辑是逐个调用addData,那addData里的notifyDataSetChanged已经能触发更新;但如果是直接替换整个数据集,建议给Adapter加个批量更新的方法:

public void setDataSet(ArrayList<Words> newDataSet) {
    mDataSet.clear();
    mDataSet.addAll(newDataSet);
    notifyDataSetChanged(); // 一次性通知数据变化,比逐个add更高效
}

然后在恢复数据后调用:

mAdapter.setDataSet(restoredData);

4. 检查Words类的序列化实现

你用onSaveInstanceState保存数据时,Words必须实现Parcelable或Serializable,否则数据无法正确写入Bundle。比如实现Parcelable:

public class Words implements Parcelable {
    private String w1;
    private String w2;
    
    // 构造函数、getter/setter...
    
    // Parcelable相关方法
    protected Words(Parcel in) {
        w1 = in.readString();
        w2 = in.readString();
    }
    
    public static final Creator<Words> CREATOR = new Creator<Words>() {
        @Override
        public Words createFromParcel(Parcel in) {
            return new Words(in);
        }
        
        @Override
        public Words[] newArray(int size) {
            return new Words[size];
        }
    };
    
    @Override
    public int describeContents() {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(w1);
        dest.writeString(w2);
    }
}

最后排查小细节

  • 去掉构造函数里多余的notifyDataSetChanged():刚初始化时数据集是空的,这个通知毫无意义,反而可能干扰后续的正常更新。
  • 在getItemCount()里打Log,确认旋转后返回的size大于0:如果size是0,说明数据根本没传到Adapter里;如果size大于0但还是不渲染,那大概率是没设置LayoutManager。

按这个流程走,应该能解决onBindViewHolder不调用的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:07:32