java – ValueEventListener对于在Android中的RecyclerView的ChildEventListener

前端之家收集整理的这篇文章主要介绍了java – ValueEventListener对于在Android中的RecyclerView的ChildEventListener前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Firebase数据库用户知道有两个基本监听器用于监听数据:ValueEventListener和ChildEventListener.当我们听一个对象时,它的效果非常好,当我们收听一些对象时变得相当困难.

要指出问题,让我们假设我们有HackerNews饲料,我们听听Firebase中的“posts”对象.

当然,在我们的应用程序中有RecyclerView显示帖子,我认为最好的主意是使用FirebaseUI,但问题是我们希望在更改服务器端或测试时使用更抽象的应用程序.所以我们会使用一些适配器,但这是另一个question.

我提到两个听众,问题是哪个更好?

当我们使用ValueEventListener时,我们将获得整个集合,但是如果有任何变化,像一个用户改变了内容,我们将不得不重新加载整个数据,这意味着更多的字节通过昂贵的网络传输发送.另一个问题是当我们使用多用户时,这里是例子:

> Post有userId,但是我们要显示他的名字,所以在onDataChanged方法中,我们获取用户数据,如下所示:

postsReference.addValueEventListener(new ValueEventListener() {
     @Override
     public void onDataChange(DataSnapshot dataSnapshot) {
          for (DataSnapshot data : dataSnapshot.getChildren()) {
               Post post = data.getValue(Post.class);   
               usersReference.child(post.getUserId()).addListenerForSingleValueEvent(new ValueEventListener() {

                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            // Here we have user data
                        }

                        @Override
                        public void onCancelled(FirebaseError firebaseError) {

                        }
              });
          }
     }

     @Override
     public void onCancelled(FirebaseError firebaseError) {
     }
});

您可以看到,现在我们必须单独添加每个帖子到RecyclerView,这将给我们提示,也许我们应该使用ChildEventListener.

所以现在当我们使用ChildEventListener时,问题是一样的 – 我们必须将每个帖子分别添加到RecyclerView中,但是当有人更改帖子内容时,firebase只会发送给我们这个帖子,这意味着通过网络减少数据.

我们不喜欢单独添加post RecyclerView,因为例如:
– 很难添加加载指示器,因为我们不知道所有数据何时出现.
用户不断刷新视图,而新帖子而不是整个列表变得可见.
– 很难对该集合进行排序,我们必须在适配器中执行此操作.

使用firebase收集的最佳做法是什么,也可能比上面写的更好的解决方案?

编辑

数据方案将如下所示:

"posts" : {
    "123456" : {
      "createdAt" : 1478696885622,"content" : "This is post content","title" : "This is post title","userId" : "abc"
    },"789012" : {
      "createdAt" : 1478696885622,"content" : "This is post content 2","title" : "This is post title 2","userId" : "efg"
    }
  }
  "users" : {
    "abc" : {
      "name" : "username1"
    },"efg" : {
      "name" : "username2"
    }
  }

编辑2

我犯了一个错误 – >当事情发生变化时,Firebase不会在ValueEventListener中获取整个数据.它只得到“三角洲”,here是证明.

解决方法

这个问题有几个问题(即性能,进度指标,处理新数据,如排序).当然,你应该提出一个考虑到你的要求的优先级的解决方案. IMO的ValueEventListener和ChildEventListener都有它们的用例:

> ChildEventListener通常是同步对象列表的推荐方式.这甚至在documentation on working with lists中提到:

When working with lists,your application should listen for child events rather than the value events used for single objects.

这是因为您的客户端仅接收具有特定更新(添加删除)的已更改子项,而不是每次更新时的整个列表.因此,它允许更精细地处理列表的更新.
> ValueEventListener可以更有用,当您需要处理整个列表修改一个孩子.当您必须对RecyclerView中的列表进行排序时,就是这种情况.通过获取整个列表,对其进行排序并刷新视图的数据集,这样做更容易.另一方面,使用ChildEventListener,更难进行排序,因为只能在每个更新事件的列表中访问一个特定的子节点.

性能的角度来看,鉴于即使ValueEventListener在同步更新时也意识到“增量”,所以我认为它在客户端方面效率较低,因为客户端必须对整个列表,但这还远远优于网络方面的低效率.

关于持续刷新和进度指标,最重要的是要注意的是,Firebase数据库是一个实时数据库,因此实时数据的不断提供是固有的特征.如果不需要更新事件,您只需使用addListenerForSingleValueEvent方法只读取一次数据.如果要在加载第一个快照时显示进度指示器,也可以使用此选项:

// show progress indicator
postsReference.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        // load initial data set
        // hide progress indicator when done loading
    }

    ...
});

猜你在找的Java相关文章