如果NotifyDataSetChanged不在循环中添加数据,则不会更新

时间:2019-09-11 17:52:31

标签: java android firebase-realtime-database

我正在使用Firebase数据更新基本排行榜ListView。每当任何用户得分变化时,它都会更新。

我有一个listView:

ListView lvLeaderboard;
lvLeaderboard = findViewById(R.id.lvLeaderboard);

一个ArrayList: ArrayList<String> userLeaderboardStrings = new ArrayList<>();

ArrayAdapter:

ArrayAdapter<String> leaderboardAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, userLeaderboardStrings);

数据加载正常。问题是,如果我不将leaderboardAdapter.notifyDatSetChanged()放在迭代Firebase数据并将其添加到适配器的循环中,则它将不会更新。

但是我之所以将其排除在循环之外是为了在所有数据加载完毕后更新列表。

看,我的第一种方法是在查询数据库之前清除列表:

leaderboardAdapter.clear();

,然后查询每个用户的数据。这留下了一个小窗口,根本没有绘制ListView,因为正在获取数据。加上Firebase数据更新速度超级快(您点击按钮以提高得分,因此您可以尽可能快地点击它),它总是在更新,因此总是闪烁不亮,显示时间不会超过十分之一秒。

但是将其添加到快照迭代器之外不会运行它。

加载所有数据后,如何刷新列表视图?


//NOTE: this is all in an enclosing valueEventListener onDataChange Method

userLeaderboardStrings.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {                            
    usersListRef.child(snapshot.getKey()).addListenerForSingleValueEvent(new 
    ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Map<String, Object> userCredMap = (Map<String, Object>) 
            dataSnapshot.getValue();
            userLeaderboardStrings.add(just the name + score);                                        
            leaderboardAdapter.notifyDataSetChanged(); // This line
    }
       @Override
       public void onCancelled(@NonNull DatabaseError databaseError) {
        }
     });
   }
//I wanna put the notifyDataSetChanged Here. It wont work

1 个答案:

答案 0 :(得分:1)

    userLeaderboardStrings.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {                            
    usersListRef.child(snapshot.getKey()).addListenerForSingleValueEvent(new 
    ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Map<String, Object> userCredMap = (Map<String, Object>) 
            dataSnapshot.getValue();
            userLeaderboardStrings.add(just the name + score);                                        
            leaderboardAdapter.notifyDataSetChanged(); // This line
    }
       @Override
       public void onCancelled(@NonNull DatabaseError databaseError) {
        }
     });
   }

此事件 addListenerForSingleValueEvent 异步运行,对于每次迭代,它将创建 addListenerForSingleValueEvent 的新实例,并在每次成功调用 onDataChange 后通知ListView。 。

因此,将其放置在循环中时效果很好。

但是,如果您希望它不在循环中,那么在这种情况下,您必须检查所有 addListenerForSingleValueEvent 是否都已完成,完成后,您需要通知列表。但是这种方法似乎不是很有效,也不是很好。

您在上面所做的一切都很好。希望您理解我上面要解释的内容。