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

RecyclerView适配器接收Firebase数据后丢失数据问题求助

解决你的RecyclerView适配器数据丢失问题

嘿,我一眼就发现了你代码里的问题——你的RecyclerViewAdapter构造函数里有一段完全多余且容易混淆的代码,这很可能就是导致数据变成null的罪魁祸首!

问题根源

看你的适配器构造函数:

public RecyclerViewAdapter (final List<Submission> submissionList) {
    this.submissionList = new List<Submission>() {
        // 一堆空实现的List方法,其中get()还返回null
    };
    this.submissionList = submissionList;
}

虽然你最后把submissionList重新赋值为传入的列表,但前面这段匿名List的代码完全没必要,而且如果这段代码没被覆盖(比如你不小心注释掉了后面的赋值语句),就会导致适配器使用的是一个所有方法都返回空值的无效List——比如get()方法直接返回null,这就解释了为什么你的视图显示默认值而不是数据库数据。

另外,你在ShowActivity的onChildAdded里每次新增一条数据就创建一个新的适配器,这种做法不仅效率低下,还可能导致不必要的视图刷新问题。

修正后的代码

1. 修复RecyclerViewAdapter构造函数

把多余的匿名List代码删掉,直接引用传入的列表:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    private List<Submission> submissionList;

    // 简化构造函数,直接接收并保存列表引用
    public RecyclerViewAdapter(List<Submission> submissionList) {
        this.submissionList = submissionList;
    }

    // 其余代码保持不变(onCreateViewHolder、onBindViewHolder等)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Submission currentSubmission = submissionList.get(position);
        Log.i("submissionCheck", String.valueOf(currentSubmission));
        if (currentSubmission != null) {
            holder.title.setText(currentSubmission.title);
            holder.text.setText(currentSubmission.text);
            holder.author.setText(currentSubmission.author);
        }
    }

    @Override
    public int getItemCount() {
        return submissionList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView title, text, author;

        public ViewHolder (View view) {
            super (view);
            title = view.findViewById(R.id.title);
            text = view.findViewById(R.id.text);
            author = view.findViewById(R.id.author);
        }
    }
}

2. 优化ShowActivity的数据处理逻辑

只初始化一次适配器,新增数据后通知适配器刷新,而不是每次都创建新的适配器:

// 在ShowActivity的成员变量里声明适配器和列表
private List<Submission> submissionList = new ArrayList<>();
private RecyclerViewAdapter adapter;

// 在onCreate方法里初始化适配器和RecyclerView
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_activity_layout);
    
    recyclerView = findViewById(R.id.your_recyclerview_id);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    // 初始化适配器并设置给RecyclerView
    adapter = new RecyclerViewAdapter(submissionList);
    recyclerView.setAdapter(adapter);
    
    // 这里初始化Firebase监听
    // ... 你的Firebase数据库引用代码 ...
}

// 修改onChildAdded方法
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    Submission submission = dataSnapshot.getValue(Submission.class);
    if (submission != null && submission.title != null) {
        submissionList.add(submission);
        // 通知适配器新增了一条数据,只刷新对应的位置
        adapter.notifyItemInserted(submissionList.size() - 1);
    }
}

额外说明

  • 确保你的Firebase数据库字段名和Submission类的字段名完全一致(大小写敏感),比如数据库里是title,类里也是title——不过你说在Activity里打印正常,这部分应该没问题。
  • 建议给Submission类的字段添加getter方法,虽然Firebase可以直接访问public字段,但封装性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:44:53