Firebase数据库数据加载问题:onCreate中无法填充ListView
解决Firebase数据异步加载导致ListView初始化为空的问题
嘿,我完全懂你的困扰!Firebase Realtime Database的数据读取是异步操作,这就意味着你在onCreate()里创建并设置ArrayAdapter的时候,projetos数组还是空的——因为onDataChange()方法要等网络请求完成后才会触发,而此时onCreate()里的代码早就执行完了。
下面是修改后的解决方案,帮你在数据加载完成后自动更新ListView:
步骤说明
- 把ArrayAdapter声明为类的成员变量,这样在
onDataChange()回调里能访问到它 - 在
onDataChange()里更新数据集后,调用适配器的notifyDataSetChanged()方法,通知ListView刷新数据 - 添加监听器的移除逻辑,避免内存泄漏
修改后的完整代码
public class MainActivity extends AppCompatActivity { private DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("projetos"); private List<Projeto> projetos; private ListView listaProjetos; // 把适配器声明为成员变量 private ArrayAdapter<Projeto> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); projetos = new ArrayList<Projeto>(); listaProjetos = findViewById(R.id.lista); // 先初始化适配器并设置给ListView adapter = new ArrayAdapter<Projeto>(this, android.R.layout.simple_list_item_1, projetos); listaProjetos.setAdapter(adapter); // 添加Firebase数据监听器 mDatabase.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { // 先清空旧数据,避免重复添加 projetos.clear(); for(DataSnapshot postSnapShot : dataSnapshot.getChildren()){ Projeto projeto = postSnapShot.getValue(Projeto.class); projetos.add(projeto); } // 通知适配器数据已更新,ListView会自动刷新 adapter.notifyDataSetChanged(); // Log.i("TESTEList", "projetos tamanho = " + projetos.size()); } @Override public void onCancelled(DatabaseError databaseError) { // 可以在这里添加错误处理逻辑,比如Toast提示用户 Toast.makeText(MainActivity.this, "加载数据失败", Toast.LENGTH_SHORT).show(); } }); } @Override protected void onDestroy() { super.onDestroy(); // 移除监听器,防止内存泄漏 mDatabase.removeEventListener(mDatabase.getValueEventListener()); } }
关键原理
Firebase的addValueEventListener()是异步执行的,它不会阻塞主线程,所以onCreate()会继续执行后面的代码。当数据从Firebase服务器返回时,onDataChange()才会被调用,此时我们更新数据集并通知适配器,ListView就会显示最新的数据了。另外,每次数据有变化时,onDataChange()都会被触发,你的ListView也会自动更新,这也符合Realtime Database的实时特性~
内容的提问来源于stack exchange,提问作者Danilo Lamazales
相关产品推荐
相关产品推荐

