如何在RecyclerView上实现从Firebase数据库加载更多的分页(无限滚动)功能。

huangapple go评论72阅读模式
英文:

How to implement load more Pagination(infinite scrolling) on RecyclerView using data from Firebase database

问题

我正在尝试实现加载更多分页(无限滚动)。我正在从Firebase实时数据库获取数据。

这些数据被用于RecyclerView中。

当用户滚动时,我希望在他滚动到RecyclerView末尾时加载更多的10个项目。

我尝试在互联网上寻找解决方案,但没有找到任何解决方案。

这是我的MainActivity:-

public class MainActivity extends AppCompatActivity {

    private ArrayList<CoffeeItem> coffeeItems;
    private CoffeeAdapter coffeeAdapter;
    private Context context = MainActivity.this;
    static RecyclerView recyclerView;
    private DatabaseReference reference;
    private StorageReference mStorageRef;
    GridLayoutManager manager;
    private int currentPage = 1;
    private static final int TOTAL_ITEM_EACH_LOAD = 10;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        manager = new GridLayoutManager(this, 2);

        coffeeItems = new ArrayList<>();

        recyclerView.setLayoutManager(manager);

        reference = FirebaseDatabase.getInstance().getReference();
        mStorageRef = FirebaseStorage.getInstance().getReference();

        recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
            @Override
            public void onLoadMore(int current_page) {
                loadMoreData();
            }
        });

        init();

    }

    private void init() {

        clearAll();

        Query query = reference.child("Images");
        query.limitToFirst(TOTAL_ITEM_EACH_LOAD);
        query.startAt(currentPage * TOTAL_ITEM_EACH_LOAD);

        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {

                    CoffeeItem coffeeItem = new CoffeeItem();

                    coffeeItem.setUrl(snapshot.child("url").getValue().toString());
                    coffeeItem.setDescription(snapshot.child("description").getValue().toString());

                    coffeeItems.add(coffeeItem);
                }

                coffeeAdapter = new CoffeeAdapter(coffeeItems, context);
                recyclerView.setAdapter(coffeeAdapter);
                recyclerView.setItemAnimator(new DefaultItemAnimator());
                coffeeAdapter.notifyDataSetChanged();

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }

    private void loadMoreData() {
        currentPage++;
        init();
    }

    private void clearAll() {

        if (coffeeItems != null) {
            coffeeItems.clear();
            if (coffeeAdapter != null) {
                coffeeAdapter.notifyDataSetChanged();
            }
        }

        coffeeItems = new ArrayList<>();

    }
}
英文:

I am trying to implement load more pagination(infinite scrolling). I am getting data from Firebase realtime database.

The data is being used in RecyclerView.

As the user scrolls I want to load 10 more items when he reach the end of the recyclerView.

I tried to find solution on the internet, but didn't find any.

Here's my MainActivity :-


public class MainActivity extends AppCompatActivity {
private ArrayList&lt;CoffeeItem&gt; coffeeItems;
private CoffeeAdapter coffeeAdapter;
private Context context = MainActivity.this;
static RecyclerView recyclerView;
private DatabaseReference reference;
private StorageReference mStorageRef;
GridLayoutManager manager;
private int currentPage = 1;
private static final int TOTAL_ITEM_EACH_LOAD = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
manager = new GridLayoutManager(this,2);
coffeeItems = new ArrayList&lt;&gt;();
recyclerView.setLayoutManager(manager);
reference = FirebaseDatabase.getInstance().getReference();
mStorageRef = FirebaseStorage.getInstance().getReference();
recyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(manager) {
@Override
public void onLoadMore(int current_page) {
loadMoreData();
}
});
init();
}
private void init() {
clearAll();
Query query = reference.child(&quot;Images&quot;);
query.limitToFirst(TOTAL_ITEM_EACH_LOAD);
query.startAt(currentPage*TOTAL_ITEM_EACH_LOAD);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
CoffeeItem coffeeItem = new CoffeeItem();
coffeeItem.setUrl(snapshot.child(&quot;url&quot;).getValue().toString());
coffeeItem.setDescription(snapshot.child(&quot;description&quot;).getValue().toString());
coffeeItems.add(coffeeItem);
}
coffeeAdapter = new CoffeeAdapter(coffeeItems, context);
recyclerView.setAdapter(coffeeAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
coffeeAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void loadMoreData(){
currentPage++;
init(); 
}
private void clearAll() {
if (coffeeItems != null){
coffeeItems.clear();
if (coffeeAdapter != null) {
coffeeAdapter.notifyDataSetChanged();
}
}
coffeeItems = new ArrayList&lt;&gt;();
}
}

答案1

得分: 0

这样是行不通的:query.startAt(currentPage*TOTAL_ITEM_EACH_LOAD)。Firebase 查询不是基于偏移量,而是基于从哪个项目开始的信息。

Firebase 分页的步骤:

  1. 根据键、值或子属性的值对项目进行排序。如果没有特定的排序需求,请使用 orderByKey()
  2. 在从数据库处理项目时,跟踪最后一个项目的值和键。如果按键排序,只需要键。
  3. 当您想要加载下一页项目时,将上一页最后的值和键传递给 startAt

关于 Firebase 分页已经有数百个问题,所以我建议查看这些问题:https://stackoverflow.com/search?q=%5Bfirebase-realtime-database%5D%5Bandroid%5D+pagination

英文:

This won't work: query.startAt(currentPage*TOTAL_ITEM_EACH_LOAD). Firebase queries are not based on offsets, but on knowing at what item to start.

The recipe for pagination in Firebase:

  1. Order your items on their key, their value, or the value of a child property. If you have no specific ordering need, use orderByKey().
  2. When you process the items from the database, keep track of the value and key of the last item. If you ordered by key, you only need the key.
  3. When you want to load the next page of items, pass the last value and key into startAt.

There are hundreds of questions already about pagination in Firebase, so I recommend checking those out: https://stackoverflow.com/search?q=%5Bfirebase-realtime-database%5D%5Bandroid%5D+pagination

huangapple
  • 本文由 发表于 2020年9月10日 20:34:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63829779.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定