Firebase Realtime Database Pagination in Recyclerview

Deepak Pradhan
3 min readOct 2, 2020

pagination is also known as load more functionality or infinite loading

We can both implement Linealayout or Grid Layout.

I am using a fragment to implementing this but you can do with activity also.

UsersFragment.Java

public class UserFragment extends Fragment
{

View UserFragment;
RecyclerView recycler_view_user;
// LinearLayoutManager manager; //for linear layout
NewAdapter adapter;
String last_key="",last_node="";
boolean isMaxData=false,isScrolling=false;
int ITEM_LOAD_COUNT= 10;
ProgressBar progressBar;

int currentitems,tottalitems,scrolledoutitems;


@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
UserFragment=inflater.inflate(R.layout.fragment_user,container,false);

recycler_view_user=UserFragment.findViewById(R.id.recycler_view_user);
progressBar=UserFragment.findViewById(R.id.progressBar1);
getLastKeyFromFirebase(); //43

// manager=new LinearLayoutManager(getContext());

GridLayoutManager manager = new GridLayoutManager(getContext(),2); //for grid layout


adapter=new NewAdapter(getContext());

recycler_view_user.setAdapter(adapter);
recycler_view_user.setLayoutManager(manager);
getUsers();
recycler_view_user.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);
getUsers();

}

}
});

return UserFragment;
}

private void getUsers()
{
if(!isMaxData) // 1st fasle
{
Query query;

if (TextUtils.isEmpty(last_node))
query = FirebaseDatabase.getInstance().getReference()
.child("Users")
.orderByKey()
.limitToFirst(ITEM_LOAD_COUNT);
else
query = FirebaseDatabase.getInstance().getReference()
.child("Users")
.orderByKey()
.startAt(last_node)
.limitToFirst(ITEM_LOAD_COUNT);

query.addListenerForSingleValueEvent(new ValueEventListener()
{
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
{
if(snapshot.hasChildren())
{

List<Users> newUsers = new ArrayList<>();
for (DataSnapshot userSnapshot : snapshot.getChildren())
{
newUsers.add(userSnapshot.getValue(Users.class));
}

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();

adapter.addAll(newUsers);
adapter.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
}
}

private void getLastKeyFromFirebase()
{
Query getLastKey= FirebaseDatabase.getInstance().getReference()
.child("Users")
.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();

}

@Override
public void onCancelled(@NonNull DatabaseError error)
{
Toast.makeText(getContext(), "can not get last key", Toast.LENGTH_SHORT).show();
}
});


}




}

UsersFragment.Xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_user"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"

/>

<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:visibility="gone"
/>

</RelativeLayout>

NewAdapter.Java

public class NewAdapter extends RecyclerView.Adapter<NewAdapter.NewViewHolder>
{
List<Users> usersList;
Context context;

public NewAdapter( Context context)
{
this.usersList = new ArrayList<>();
this.context = context;
}

public void addAll(List<Users> newUsers)
{
int initsize=usersList.size();
usersList.addAll(newUsers);
notifyItemRangeChanged(initsize,newUsers.size());
}


public static class NewViewHolder extends RecyclerView.ViewHolder
{
TextView name;

public NewViewHolder(@NonNull View itemView)
{
super(itemView);
name=itemView.findViewById(R.id.name);

}
}

@NonNull
@Override
public NewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View itemView= LayoutInflater.from(context).inflate(R.layout.user_layout_items,parent,false);
return new NewViewHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull NewViewHolder holder, int position)
{
holder.name.setText(usersList.get(position).getName());
}

@Override
public int getItemCount()
{
return usersList.size();
}


}

ModelClass

Users.java

package com.xscroll.infinitescroll.Model;

public class Users
{
private String id,name,email;

public Users()
{

}

public Users(String id, String name, String email)
{
this.id = id;
this.name = name;
this.email = email;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}
Firebase Database structure

Result:

--

--