Android 从Firebase加载到ListView的重复对象
当我向listview添加新消息时,会添加我拥有的消息和新消息,因此它会将相同的信息放两次 我想用Firebase加载listview中的最后一条消息,我在create()中有以下函数:Android 从Firebase加载到ListView的重复对象,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,当我向listview添加新消息时,会添加我拥有的消息和新消息,因此它会将相同的信息放两次 我想用Firebase加载listview中的最后一条消息,我在create()中有以下函数: firebase=newfirebase(firebase\u URL).child(firebase\u child+“/”+SharedReferences.getString(“chatKey”,null).toString()+“/room/”; firebase.child(“messages”).a
firebase=newfirebase(firebase\u URL).child(firebase\u child+“/”+SharedReferences.getString(“chatKey”,null).toString()+“/room/”;
firebase.child(“messages”).addValueEventListener(新的ValueEventListener(){
@凌驾
公共无效onDataChange(数据快照快照){
if(Snapshot.getValue()!=null){
Iterable迭代器=Snapshot.getChildren();
itemMessage itemData;
for(DataSnapshot值:迭代器){
itemData=value.getValue(itemMessage.class);
添加(itemData.getMessage().toString());
}
mConversation.setAdapter(mcdata适配器);
}
}
对于添加新消息:
sendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ChatActivity.this);
SharedPreferences.Editor editor = sharedPreferences.edit();
// editor.clear().commit();
if( sharedPreferences.getString("chatKey", null) != null && sharedPreferences.getString("chatKey", null).toString() != "" ){
messageLevel = new Firebase(FIREBASE_URL+sharedPreferences
.getString("chatKey", null)
.toString()+"/room/")
.child("messages");
Map<String, Object> messageData = new HashMap<String, Object>();
messageData.put( "message", message.getText().toString() );
messageData.put( "userTo", 1 );
messageData.put( "userFrom",2 );
messageLevel
.push()
.setValue(messageData);
mCDataAdatapter.add( message.getText().toString() );
mConversation.setAdapter( mCDataAdatapter );
message.setText("");
}
}
});
sendMessage.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
SharedReferences SharedReferences=PreferenceManager.getDefaultSharedReferences(ChatActivity.this);
SharedReferences.Editor=SharedReferences.edit();
//editor.clear().commit();
if(sharedReferences.getString(“chatKey”,null)!=null&&sharedReferences.getString(“chatKey,null”).toString()!=“”){
messageLevel=新Firebase(Firebase\u URL+共享引用
.getString(“聊天键”,null)
.toString()+“/room/”)
.儿童(“信息”);
Map messageData=newhashmap();
messageData.put(“message”,message.getText().toString());
messageData.put(“userTo”,1);
messageData.put(“userFrom”,2);
消息级别
.push()
.setValue(messageData);
添加(message.getText().toString());
mConversation.setAdapter(mcdata适配器);
message.setText(“”);
}
}
});
除了通过Firebase listener之外,您不应该以任何其他方式添加消息,但我猜您是在发送消息后在第行mCDataAdatapter.add(message.getText().toString());
中添加消息。原因是Firebase在添加新消息时会自动调用onDataChange
我还建议您使用
ChildEventListener
,否则您应该清除整个ListView
或过滤更改以避免相同的数据。您正在这样做吗?当您使用addValueEventListener()时
,处理程序将立即使用节点的当前值调用,随后每次节点值更改时都会调用。每次调用处理程序时,它都会获取您侦听的整个内容的快照。因此,如果从3条消息开始
message 1
message 2
message 3
您的onDataChange()
将通过以下3条消息被调用。如果您随后添加第4条消息:
message 1
message 2
message 3
message 4
您的onDataChange()
将被全部4条消息调用。如果您坚持使用当前代码,您必须自己检测并删除重复的代码
幸运的是,Firebase SDK还允许您通过调用链接文档中的addChildEventListener()
,进行以下操作:
ref.addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// A new comment has been added, add it to the displayed list
Comment comment = dataSnapshot.getValue(Comment.class);
}
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Comment newComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
}
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String commentKey = dataSnapshot.getKey();
}
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Comment movedComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "postComments:onCancelled", databaseError.toException());
}
});
如果使用此方法,最初将调用3次onchildaded()
,每个项调用一次。然后,当添加第4个子项时,仅使用第4项再次调用onchildaded()
ref.addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// A new comment has been added, add it to the displayed list
Comment comment = dataSnapshot.getValue(Comment.class);
}
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Comment newComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
}
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String commentKey = dataSnapshot.getKey();
}
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Comment movedComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "postComments:onCancelled", databaseError.toException());
}
});