Firebase RecyclerView首次加载无数据,二次进入才显示问题咨询
搞定Firebase数据需两次进入才加载的问题
嘿,我来帮你捋清楚为啥会出现这种情况,还有怎么修复它~
问题到底出在哪?
首先得明白:Firebase的addValueEventListener是异步工作的——你调用它之后,代码不会等着Firebase返回数据,而是直接往下跑。看你写的代码:
- 你刚注册完监听,立刻就去拿
listArrayList.size(),这时候onDataChange回调还没触发呢,列表里根本没数据,所以第一次进页面会显示"No Quiz's Found"。 - 等你返回再进来的时候,上一次回调已经把数据加到
listArrayList里了,这时候size大于0,自然就能显示列表了。
另外,你每次判断size的时候都重新初始化RecyclerView、布局管理器和Adapter,这完全是重复劳动,没必要哈。
怎么改?
核心就是:所有和数据相关的UI更新逻辑,都要放到onDataChange回调里面,因为只有这里能保证数据已经加载完成了。同时还要注意清空旧数据,通知Adapter更新,避免重复内容。
给你改好的代码参考:
// 先把RecyclerView的初始化工作做好,只做一次就行 mRecyclerView = findViewById(R.id.recycleview); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLayoutManager); // 先给Adapter传空列表,后面再更新数据 mAdapter = new TableTrackerAdapter(this, listArrayList); mRecyclerView.setAdapter(mAdapter); db = FirebaseDatabase.getInstance().getReference(); dbRef = db.child("Table List"); dbRef.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { // 先清空旧数据,不然每次回调都会重复加 listArrayList.clear(); for (DataSnapshot child : dataSnapshot.getChildren()) { listArrayList.add(child.getValue(String.class)); } int sz = listArrayList.size(); // 根据数据量调整UI显示 if(sz == 0){ tvNoData.setVisibility(View.VISIBLE); tvNoData.setText("No Quiz's Found\n\nClick On Make New Quiz"); } else { tvNoData.setVisibility(View.INVISIBLE); } // 告诉Adapter数据变了,刷新列表 mAdapter.notifyDataSetChanged(); } @Override public void onCancelled(DatabaseError databaseError) { // 这里一定要加错误处理,不然出问题都不知道为啥 Toast.makeText(YourActivity.this, "数据加载失败: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } });
额外的小建议
- 如果不需要实时监听数据变化,只是加载一次的话,可以用
addListenerForSingleValueEvent代替addValueEventListener,减少不必要的回调。 - 确保
listArrayList是全局变量,或者在回调里能访问到,别搞成局部变量导致数据加不进去。 - 错误回调
onCancelled真的很重要,不然哪天Firebase权限配置错了,你连报错信息都看不到。
内容的提问来源于stack exchange,提问作者Vector
相关产品推荐
相关产品推荐

