如何防止分页中的重复项目-Firebase实时数据库



滚动到RecyclerView的底部后,将再次从Start获取数据,最终以无限滚动结束,永远不会结束。我正在使用Firebase实时数据库

这是我的代码:

String last_key = "", last_node = "";
boolean isMaxData = false, isScrolling = false;
int ITEM_LOAD_COUNT = 10;
int currentitems, tottalitems, scrolledoutitems;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
isScrolling = true;
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
currentitems = manager.getChildCount();
tottalitems = manager.getItemCount();
scrolledoutitems = manager.findFirstVisibleItemPosition();
if (isScrolling && currentitems + scrolledoutitems == tottalitems) {
//  Toast.makeText(getContext(), "fetch data", Toast.LENGTH_SHORT).show();
isScrolling = false;
//fetch data
progressbar.setVisibility(View.VISIBLE);
Log.e("On","Scrolled, Reached Bottom");
getUsers();
}
}
});

这就是我从数据库中获取项目的方式:

private void getUsers() {
if (!isMaxData) // 1st fasle
{
Query query;
if (TextUtils.isEmpty(last_node))
query = FirebaseDatabase.getInstance().getReference("ShopCategories").child(recPosition).child("items")
.orderByKey()
.limitToFirst(ITEM_LOAD_COUNT);
else
query = FirebaseDatabase.getInstance().getReference("ShopCategories").child(recPosition).child("items")
.orderByKey()
.startAt(last_node)
.limitToFirst(ITEM_LOAD_COUNT);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.hasChildren()) {
List<TrendingModel> newUsers = new ArrayList<>();
for (DataSnapshot userSnapshot : snapshot.getChildren()) {
newUsers.add(userSnapshot.getValue(TrendingModel.class));
Log.e("NewUsersList",""+userSnapshot.child("title").getValue(String.class));
}
//                        Log.e("NewUsersList",""+newUsers);
last_node = newUsers.get(newUsers.size() - 1).getId();    //10  if it greater than the toatal items set to visible then fetch data from server
if (!last_node.equals(last_key))
newUsers.remove(newUsers.size() - 1);    // 19,19 so to renove duplicate removeone value
else
last_node = "end";
// Toast.makeText(getContext(), "last_node"+last_node, Toast.LENGTH_SHORT).show();
trendingAdapter.addAll(newUsers);
trendingAdapter.notifyDataSetChanged();

} else   //reach to end no further child avaialable to show
{
isMaxData = true;
}
progressbar.setVisibility(View.GONE);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
} else {
progressbar.setVisibility(View.GONE); //if data end
}
}

这是我从FirebaseReal-time数据库获取最后一个密钥的代码:

private void getLastKeyFromFirebase() {
Query getLastKey = FirebaseDatabase.getInstance().getReference("ShopCategories").child(recPosition).child("items")
.orderByKey()
.limitToLast(1);
getLastKey.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot lastkey : snapshot.getChildren())
last_key = lastkey.getKey();
//   Toast.makeText(getContext(), "last_key"+last_key, Toast.LENGTH_SHORT).show();
Log.e("LastKey",""+last_key);
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Toast.makeText(CategoryDetailActivity.this, "can not get last key", Toast.LENGTH_SHORT).show();
}
});

}

这是Adapter类代码的一部分:(不要放整个代码,因为它可能会变得混乱(

List<TrendingModel> trendingModelList;
Context context;
public TrendingAdapter(Context context) {
this.trendingModelList = new ArrayList<>();
Log.e("New","Instance creating");
this.context = context;
}
public void addAll(List<TrendingModel> newUsers) {
int initsize = trendingModelList.size();
trendingModelList.addAll(newUsers);
notifyItemRangeChanged(initsize, newUsers.size());
}

和模型类:(不放整个代码,因为它可能会变得混乱(:

public String getId() {
return id;
}

您可以跳过应用程序代码中的重复项,也可以在此处使用startAfter操作而不是startAt

query = FirebaseDatabase.getInstance().getReference("ShopCategories").child(recPosition).child("items")
.orderByKey()
.startAfter(last_node) // 👈
.limitToFirst(ITEM_LOAD_COUNT);