将Firebase中的重复对象加载到ListView中 [英] Duplicate objects from Firebase loaded into ListView

查看:44
本文介绍了将Firebase中的重复对象加载到ListView中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我向列表视图中添加新消息时,这会同时添加我拥有的消息和新消息,因此它将相同的信息放置两次.

When I add new message to a listview, that adds message that I have and the new message, so it puts the same information twice.

我想在Firebase的列表视图中加载最后一条消息,我在create()中加入了以下功能:

I want to load last messages in a listview with Firebase, I have the follow function into create():

firebase = new Firebase(FIREBASE_URL).child(FIREBASE_CHILD + "/" + sharedPreferences.getString("chatKey", null).toString() + "/room/");

firebase.child("messages").addValueEventListener(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot Snapshot) {

        if (Snapshot.getValue() != null) {
            Iterable<DataSnapshot> iterator = Snapshot.getChildren();
            itemMessage itemData;

            for(DataSnapshot value : iterator){
                itemData = value.getValue( itemMessage.class );
                mCDataAdatapter.add( itemData.getMessage().toString() );
            }

           mConversation.setAdapter( mCDataAdatapter );
        }
    }

并添加新消息:

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("");

        }


    }
});

推荐答案

使用 addValueEventListener()时,将立即使用节点的当前值调用处理程序,随后每次调用该值时节点的变化.每次调用处理程序时,它都会获取您所侦听的全部内容的快照.因此,如果您以3条消息开头

When you use addValueEventListener(), your handler will be invoked immediately with the current value of the node and subsequently each time the value of the node changes. Each time the handler is invoked, it gets a snapshot of the entire contents that you listen for. So if you start with 3 messages

message 1
message 2
message 3

您的 onDataChange()将被这3条消息调用.如果您随后添加第四条消息:

Your onDataChange() will get invoked with these 3 message. If you then add a 4th message:

message 1
message 2
message 3
message 4

您的 onDataChange()将被所有4条消息调用.如果您坚持使用当前代码,则必须自己检测并删除重复项.

Your onDataChange() will get invoked with all 4 messages. If you stick to your current code, you will have to detect and remove the duplicates yourself.

幸运的是,Firebase SDK还允许您收听 addChildEventListener(),> child 级别更改.从链接的文档中:

Luckily the Firebase SDK also allows you to listen for child level changes by calling addChildEventListener(). From the linked documentation:

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());
    }
});

如果使用这种方法,最初,您的 onChildAdded()将被调用3次,每项一次.然后,当您添加第四个孩子时, onChildAdded()将再次被调用,而仅是第四个项目.

If you use this approach, initially your onChildAdded() will be called 3 times, once for each item. Then when you add the 4th child, you onChildAdded() will be invoked again with just the 4th item.

这篇关于将Firebase中的重复对象加载到ListView中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆