英文:
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<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.setOnScrollListener(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<>();
}
}
答案1
得分: 0
这样是行不通的:query.startAt(currentPage*TOTAL_ITEM_EACH_LOAD)
。Firebase 查询不是基于偏移量,而是基于从哪个项目开始的信息。
Firebase 分页的步骤:
- 根据键、值或子属性的值对项目进行排序。如果没有特定的排序需求,请使用
orderByKey()
。 - 在从数据库处理项目时,跟踪最后一个项目的值和键。如果按键排序,只需要键。
- 当您想要加载下一页项目时,将上一页最后的值和键传递给
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:
- Order your items on their key, their value, or the value of a child property. If you have no specific ordering need, use
orderByKey()
. - 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.
- 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论