简体   繁体   English

在 Firebase 数据库 onDataChange 上更新 RecyclerView

[英]Updating RecyclerView On Firebase Database onDataChange

I am new to recyclerView.我是 recyclerView 的新手。 I am creating an app which in which when i send my data to firebase database, a image view with check mark with my data in recyclerView comes in stating that my data has reached database.我正在创建一个应用程序,当我将数据发送到firebase数据库时, recyclerView中带有复选标记的图像视图会显示我的数据已到达数据库。

I did this by creating a child key which sets value from processing to reached when data has reached the servers.我通过创建一个子键来做到这一点,该子键在数据到达服务器时将值从 processing 设置为 reached 。

I also created a imageView which sets its resource as check mark if message has reached.我还创建了一个imageView ,如果消息已到达,它将其资源设置为复选标记。 Till now it works fine.到现在为止一切正常。 But the issue is that my recyclerView doesn't refresh on the same moment.但问题是我的 recyclerView 不会同时刷新。

If I press Back Button (Even Close The Activity) and then come back to same activity, image view is now there.如果我按下后退按钮(甚至关闭活动)然后返回到相同的活动,图像视图现在就在那里。 Hence, you can understand that my task done till now is working properly.因此,您可以理解我到目前为止完成的任务工作正常。 I even know that by adding listener to my recyclerView can handle this issue.我什至知道通过将侦听器添加到我的 recyclerView 可以解决这个问题。

FirebaseDatabase.getInstance().getReference().child("message").push().setValue(newMessage, new DatabaseReference.CompletionListener() {
  @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
      databaseReference.child("reachedServer").setValue("reached");
    }
});

But I have tried every thing to refresh my recyclerView on child change.但是我已经尝试了所有方法来刷新我的 recyclerView 子更改。

But just it does not work.I have now erased my commands when child changes in firebase .但它不起作用。当孩子在firebase中发生变化时,我现在已经删除了我的命令。 Please help me so that I can refresh my recyclerView when child changes.请帮助我,以便我可以在孩子更改时刷新我的recyclerView

PS .附言 I store my data in my custom class and I also use custom adapter.我将数据存储在自定义类中,并且还使用自定义适配器。

To refresh the adapter you can use:要刷新适配器,您可以使用:

adapter.notifyDataSetChanged();

notifyDataSetChanged通知数据集已更改

void notifyDataSetChanged () void notifyDataSetChanged ()

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.通知附加的观察者底层数据已更改,任何反映数据集的视图都应自行刷新。

more info here: https://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()更多信息在这里: https://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()

Yay, I did it.耶,我做到了。
I did this In OnChildChanged Method Of childEventListener of my database reference.我在我的数据库引用的 childEventListener 的 OnChildChanged 方法中这样做了。

                @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                if (dataSnapshot.getValue() != null) {
                    Message newMessage = dataSnapshot.getValue(Message.class);
                    if (newMessage != null) {
                        for (int i = 0; i < myArrayList().size(); i++) {
                            if (myArrayList().get(i).timestamp == newMessage.timestamp) {
                                myArrayList().remove(i);
                                myArrayList().add(i, newMessage);
                                break;
                            }
                        }
                    }
                    adapter.notifyDataSetChanged();
                }
            }

try this试试这个

  adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            super.onItemRangeInserted(positionStart, itemCount);

            recycler_view.setAdapter(adapter);
            adapter.notifyDataSetChanged();

        }
    });

Your CompletionListener is triggered when data is already inserted, it means you do not need any additional changes to your database in order to display something on your client device(the same one, which was making changes).当数据已经插入时,您的CompletionListener被触发,这意味着您不需要对数据库进行任何额外的更改,以便在您的客户端设备上显示某些内容(同一个,正在进行更改)。

Simply: inside CompletionListener update specific recycleView record.很简单:在CompletionListener内部更新特定的 recycleView 记录。 You can do this with notifyItemChanged(position) or notifyItemChanged(position, payload) , considering 1st call you have to change data record which is used inside onBindViewHolder in your adapter, or you can set a flag to that adapter which will be used in onBindViewHolder .您可以使用notifyItemChanged(position)notifyItemChanged(position, payload)执行此操作,考虑到第一次调用您必须更改适配器中onBindViewHolder内部使用的数据记录,或者您可以为将在onBindViewHolder中使用的适配器设置一个标志. 2nd call gives you availability to pass any additional data.第二次通话使您可以传递任何其他数据。

Keep in mind that notifyItemChanged(position, payload) call is 1st and it has notifyItemChanged(position) call inside it.请记住, notifyItemChanged(position, payload)调用是第一个,它内部有notifyItemChanged(position)调用。 Do you need any additional info?您需要任何其他信息吗?

To refresh the adapter only for the item changed use the following code on your onChildChaged() method:要仅为更改的项目刷新适配器,请在 onChildChaged() 方法中使用以下代码:

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
        Message message = dataSnapshot.getValue(Message.class);
        
        for (int i = 0; i < messagesList.size(); i++) {
            if (messagesList.get(i).getMessageID().equals(message.getMessageID())) {
                messagesList.set(i, message);
                adapter.notifyItemChanged(i);
                break;
            }
        }
}

Make sure you have a unique message ID for each message and its getter in your Message model class, in the example above this was called MessageID and the getter getMessageID().确保您的消息模型类中的每条消息及其 getter 都有一个唯一的消息 ID,在上面的示例中,这称为 MessageID 和 getter getMessageID()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM