使用firebase在无尽的回收器视图中进行分页

Posted

技术标签:

【中文标题】使用firebase在无尽的回收器视图中进行分页【英文标题】:Pagination in endless recycler view with firebase 【发布时间】:2017-09-03 12:33:56 【问题描述】:

我正在开发 Q/A 应用程序。我已成功加载来自 firebase 的问题。但我无法从像数据库这样的 Firebase 应用分页。以及如何识别我们已经到达回收站视图的末尾,以便可以加载接下来的几个问题。

【问题讨论】:

你能发布你的适配器代码吗? 【参考方案1】:

要识别我们已到达RecyclerView 的末尾,您可以使用此类EndlessRecyclerOnScrollListener.java

要加载更多下一个问题,您应该在Question class 中再定义一个字段,例如数字

public class Question 
    private int number; // it must unique and auto increase when you add new question
    ...

然后,当您从FireBase 加载问题时,您可以这样做

public class MainActivity extends AppCompatActivity 
    private static final int TOTAL_ITEM_EACH_LOAD = 10;
    private DatabaseReference mDatabase;
    final List<Question> questionList = new ArrayList<>();

    private int currentPage = 0;

    private RecyclerView recyclerView;
    private RecyclerViewAdapter mAdapter; 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        ...
        // init and set layout manager for your RecyclerView
        ...
        mAdapter = new RecyclerViewAdapter(questionList);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) 
            @Override
            public void onLoadMore(int current_page)  // when we have reached end of RecyclerView this event fired
                loadMoreData();
            
        );
        loadData(); // load data here for first time launch app
    

    private void loadData() 
        // example
        // at first load : currentPage = 0 -> we startAt(0 * 10 = 0)
        // at second load (first loadmore) : currentPage = 1 -> we startAt(1 * 10 = 10)
        mDatabase.child("questions")
                .limitToFirst(TOTAL_ITEM_EACH_LOAD)
                .startAt(currentPage*TOTAL_ITEM_EACH_LOAD)
                .orderByChild("number")
                .addValueEventListener(new ValueEventListener() 
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) 
                        if(!dataSnapshot.hasChildren())
                            Toast.makeText(MainActivity.this, "No more questions", Toast.LENGTH_SHORT).show();
                            currentPage--;
                        
                        for (DataSnapshot data : dataSnapshot.getChildren()) 
                            Question question = data.getValue(Question.class);
                            questionList.add(question);
                            mAdapter.notifyDataSetChanged();
                        
                    

                   @Override public void onCancelled(DatabaseError databaseError) );
    

    private void loadMoreData()
        currentPage++;
        loadData();
    

Here is my DEMO project

【讨论】:

你的类支持的最低 API 级别是多少。 @RishabhMaurya 来自 1 级 好的,我会实现的,然后通知你。 @RishabhMaurya 如果您有问题,请查看底部的我的 DEMO。它可能会有所帮助 @PhanVanLinh 我正在编写相同的代码.. 分页运行良好,但是在执行分页调用时它会清除以前的数据.. 我没有在任何地方写清晰的数据列表.. 请有任何建议跨度> 【参考方案2】:

要检查你是否到达了RecyclerView的底部,你可以使用如下的onScrolled监听器,这里的if条件很重要,它定义了用户何时到达底部。

mRV.addOnScrollListener(new RecyclerView.OnScrollListener() 

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) 
                super.onScrolled(recyclerView, dx, dy);

                mTotalItemCount = mLayoutManager.getItemCount();
                mLastVisibleItemPosition = mLayoutManager.findLastVisibleItemPosition();

                if (!mIsLoading && mTotalItemCount <= (mLastVisibleItemPosition + mPostsPerPage)) 
                    getUsers(mAdapter.getLastItemId());
                    mIsLoading = true;
                
            
        );

其次,您可以使用startAtlimitToFirst方法批量获取问题,如下所示:

query = FirebaseDatabase.getInstance().getReference()
                    .child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
                    .orderByKey()
                    .startAt(nodeId)
                    .limitToFirst(mPostsPerPage);

我创建了一个开源应用程序,它可以准确地展示它是如何完成的。请看:https://blog.shajeelafzal.com/2017/12/13/firebase-realtime-database-pagination-guide-using-recyclerview/

【讨论】:

【参考方案3】:

您可以创建Firebase Queries到您的FirebaseRecyclerAdapter,使用startAtlimitToFirst批量下载记录。

limitToFirst 页面大小会随着事件(例如点击或pull to refresh)而增加。

【讨论】:

我希望 recyclerview 在从 firebase 加载下一组固定项目时显示进度条。 您可以显示/关闭SwipeRefreshLayout 调用setRefreshing

以上是关于使用firebase在无尽的回收器视图中进行分页的主要内容,如果未能解决你的问题,请参考以下文章

从 Firebase 中的嵌套查询填充回收站视图

如何根据位置从“回收”视图中删除Firebase数据库密钥

使用警报对话框时在回收站视图中从 Firebase 中删除项目

无法从 firebase 回收器视图中的 firebase 实时数据库中获取嵌套数据

使用 Firebase Firestore 进行分页 - swift 4

如何使用分页库在回收站视图中添加日期分隔符?