【问题标题】:How to pass a database reference (coming from Callback) to FirebaseRecyclerAdapter如何将数据库引用(来自回调)传递给 FirebaseRecyclerAdapter
【发布时间】:2018-06-18 21:18:19
【问题描述】:

我处于必须从 Callback 获取 firebase 数据库引用的情况。它工作得很好,因为我能够读/写数据库。

public void readData(final MyCallback myCallback) {
    mCurrentUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String university = dataSnapshot.child("university").getValue().toString();
            String groupid = dataSnapshot.child("groupid").getValue().toString();
            //Having acquired university and group ID, now we can get reference to group members list
            mMembersDatabase = FirebaseDatabase.getInstance().getReference().child("Universities").child(university).child("Groups").child(groupid).child("Members");
            myCallback.onCallback(mMembersDatabase);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

然后,在我的活动的 onStart() 方法中,我正在创建我的 FirebaseRecyclerAdapter。因为它需要 4 个参数:

  • 模型类
  • 资源布局文件
  • 视图持有者类
  • firebase 数据库参考

我需要将我从回调中获得的 firebase 数据库引用作为参数传递。 我在 onStart() 中尝试了以下操作,但它不起作用。

    readData(new MyCallback() {
        @Override
        public void onCallback(DatabaseReference databaseReference) {


           FirebaseRecyclerAdapter<Groupmates, GroupmatesViewHolder> firebaseRecyclerAdapter =
            new FirebaseRecyclerAdapter <Groupmates, GroupmatesViewHolder> (
                    Groupmates.class,
                    R.layout.users_single_layout,
                    GroupmatesViewHolder.class,
                    databaseReference
            ) {
                @Override
                protected  void populateViewHolder(final GroupmatesViewHolder groupmatesViewHolder, final Groupmates groupmates, final int position) {
                                 //SOME LOGIC HERE
                }
            };
    //Finally, setting the ready adapter to the RecyclerView
    mGroupmatesList.setAdapter(firebaseRecyclerAdapter);

        }
    });

如果我尝试在回调之外创建 FirebaseRecyclerAdapter,则会收到空对象引用异常。

我真的无法摆脱它。任何建议都会有所帮助。

【问题讨论】:

  • 为什么需要在onStart()中调用readData()
  • 它实际上是一个片段,是选项卡布局的一部分。我认为选择特定选项卡时,应加载数据。 span>

标签: java android firebase firebase-realtime-database android-recyclerview


【解决方案1】:

经过一天的研究,我终于找到了解决方案。我要感谢 @Alex Mamo 提供的正确指导和方向。但是,这还不够解决问题。这就是为什么我要回答我自己的问题。

Callback 获得FirebaseDatabaseReference 后,我的回收站视图仍未填充。因此,简单地通过Callback 获取数据库引用可能足以看到最终结果。在对this question 的回答以及@Alex Mamo 提供的建议和指导的帮助下,我能够解决这个问题。

所以答案很简单:我只是在onCreateView() 中调用了我的Callback。然后在Callback Method 中创建了我的FirebaseReyclerAdapter。创建适配器时,在将适配器设置为RecyclerView 之前,需要将AdapterDataObsever 添加到适配器。

firebaseRecyclerAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
                @Override
                public void onItemRangeInserted(int positionStart, int itemCount) {
                    super.onItemRangeInserted(positionStart, itemCount);
                    int groupmate_count = firebaseRecyclerAdapter.getItemCount();
                    int lastVisiblePosition = mLinearLayoutManager.findLastVisibleItemPosition();
                    // If the recycler view is initially being loaded or the
                    // user is at the bottom of the list, scroll to the bottom
                    // of the list to show the newly added message.
                    if (lastVisiblePosition == -1 ||  (positionStart >= (groupmate_count - 1) && lastVisiblePosition == (positionStart - 1))) {
                        mGroupmatesList.scrollToPosition(positionStart);
                    }
                }
            });

这很好用。希望它也对其他人有所帮助。

【讨论】:

    【解决方案2】:

    如果我是你,我会将FirebaseRecyclerAdapter 的声明移到onDataChange() 中,这样你就可以轻松地将mMembersDatabase 传递给构造函数,然后像这样更改回调:

    public interface MyCallback {
        void onCallback(FirebaseRecyclerAdapter firebaseRecyclerAdapter);
    }
    

    使用如下代码:

    public void readData(final MyCallback myCallback) {
        mCurrentUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String university = dataSnapshot.child("university").getValue().toString();
            String groupid = dataSnapshot.child("groupid").getValue().toString();
            //Having acquired university and group ID, now we can get reference to group members list
            mMembersDatabase = FirebaseDatabase.getInstance().getReference().child("Universities").child(university).child("Groups").child(groupid).child("Members");
    
            FirebaseRecyclerAdapter<Groupmates, GroupmatesViewHolder> firebaseRecyclerAdapter =
            new FirebaseRecyclerAdapter <Groupmates, GroupmatesViewHolder> (
                Groupmates.class,
                R.layout.users_single_layout,
                GroupmatesViewHolder.class,
                mMembersDatabase
            ) {
                 @Override
                 protected  void populateViewHolder(final GroupmatesViewHolder groupmatesViewHolder, final Groupmates groupmates, final int position) {
                     //SOME LOGIC HERE
                 }
            };
            myCallback.onCallback(firebaseRecyclerAdapter);
        }
    
        @Override
            public void onCancelled(DatabaseError databaseError) {}
        });
    }
    

    然后在你的 onStart() 中,使用这个:

    readData(new MyCallback() {
        @Override
        public void onCallback(FirebaseRecyclerAdapter firebaseRecyclerAdapter) {
            mGroupmatesList.setAdapter(firebaseRecyclerAdapter);
        }
    });
    

    【讨论】:

    • 即使我按照您的建议进行操作,它仍然无法正常工作。我的片段没有填充组成员。我在 RUN 部分收到以下内容:E/RecyclerView: No adapter attached; skipping layout
    • 由于回调,这不会发生。当您在选项卡之间切换时会显示该错误。假设您有一个 viewPager,假设有 3 个标签,请使用以下代码:viewPager.setOffscreenPageLimit(2);
    • 其实我TabLayout中的群组成员列表是第一个标签。所以,我没有在选项卡之间切换(没有必要)。当我的活动加载时,它只是显示一个空屏幕。根本没有数据。
    • 检查here该错误的原因。这与回调无关。
    • 不幸的是,它没有帮助。我花了很多时间在调试上。我已经使用虚拟数据库参考和相同的随机值测试了我的FirebaseRecyclerAdapter。令人惊讶的是,它正在工作。所以,我得出的结论是,来自CallbackmMembersDatabase 仍然存在问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 2013-08-09
    相关资源
    最近更新 更多