I'm trying to include pagination in my app what I want that for eg in my firebase I have 500 images that are to be shown in the recycler view what I want is first 10 or 15 images are loaded in the recycler view at the beginning and when the user reaches to the end of the last item(image) it loads next 10 images (just like Instagram or facebook )
Note:- if anyone wants more reference of my code please tell me I will update my question
Here is my code
Home_Fragment.java
private boolean loading = true;
private int pastVisibleItems, visibleItemCount, totalItemCount;
@SuppressLint("SourceLockedOrientationActivity")
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
MaterialToolbar materialToolbar = view.findViewById(R.id.toolbar);
materialToolbar.setOnMenuItemClickListener(toolbarItemClickListener);
postRecyclerView = view.findViewById(R.id.recyclerViewHome);
shimmerFrameLayout = view.findViewById(R.id.shimmerEffect);
// this is for one item per scroll
// SnapHelper snapHelper = new PagerSnapHelper();
// snapHelper.attachToRecyclerView(verticalRecyclerView);
postRecyclerView.setAdapter(postsAdapter);
// listState = savedInstanceState.getParcelable("ListState");
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
postRecyclerView.setLayoutManager(
staggeredGridLayoutManager
);
getData();
postRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = staggeredGridLayoutManager.getChildCount();
totalItemCount = staggeredGridLayoutManager.getItemCount();
int[] firstVisibleItems = null;
firstVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
if (firstVisibleItems != null && firstVisibleItems.length > 0) {
pastVisibleItems = firstVisibleItems[0];
}
if (loading) {
if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
loading = false;
getData();
Log.d("tag", "LOAD NEXT ITEM");
}
}
}
});
// setupFirebaseAuth();
shimmerFrameLayout.startShimmer();
mUploads = new ArrayList<>();
postsAdapter = new PostAdapter_Home(getContext(), mUploads);
postRecyclerView.setAdapter(postsAdapter);
postRecyclerView.scrollToPosition(Home_Fragment.saved_position);
return view;
}
private void getData() {
databaseReference.addValueEventListener(new ValueEventListener() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
shimmerFrameLayout.stopShimmer();
shimmerFrameLayout.setVisibility(View.GONE);
postRecyclerView.setVisibility(View.VISIBLE);
mUploads.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Upload upload = dataSnapshot.getValue(Upload.class);
assert upload != null;
upload.setmKey(dataSnapshot.getKey());
mUploads.add(upload);
}
}
postsAdapter.setUploads(mUploads);
//notify the adapter
postsAdapter.notifyDataSetChanged();
loading = true;
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
loading = true;
}
});
}
PostAdapter_Home.java // Adapter Class
public class PostAdapter_Home extends RecyclerView.Adapter<PostAdapter_Home.PostViewHolder> {
public static List<Upload> mUploads;
public Context mcontext;
public PostAdapter_Home(Context context, List<Upload> uploads) {
mUploads = uploads;
mcontext = context;
}
@NonNull
@Override
public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
view = LayoutInflater.from(mcontext).inflate(R.layout.ex_home, parent, false);
return new PostViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
Shimmer shimmer = new Shimmer.ColorHighlightBuilder()
.setBaseColor(Color.parseColor("#F3F3F3"))
.setBaseAlpha(1)
.setHighlightColor(Color.parseColor("#E7E7E7"))
.setHighlightAlpha(1)
.setDropoff(50)
.build();
ShimmerDrawable shimmerDrawable = new ShimmerDrawable();
shimmerDrawable.setShimmer(shimmer);
Upload uploadCurrent = mUploads.get(position);
Glide.with(mcontext)
.load(uploadCurrent.getmImageUrl())
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.placeholder(shimmerDrawable)
.centerCrop()
.fitCenter()
.into(holder.imageView);
// holder.imageView.setOnClickListener(view -> changeScaleType(holder, position));
}
@Override
public int getItemCount() {
return mUploads.size();
}
public void setUploads(List<Upload> uploads){
mUploads=uploads;
}
public static class PostViewHolder extends RecyclerView.ViewHolder {
private final ShapeableImageView imageView;
public PostViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imagePostHome);
}
}
}
Update // Added Upload.java file code as requested in the comment section
Upload.java
package com.example.myappnotfinal.AdaptersAndMore;
import com.google.firebase.database.Exclude;
public class Upload {
private String mImageUrl;
private String mKey;
private String mUserName;
private String mComment;
public Upload() {
}
public Upload(String imageUrl) {
mImageUrl = imageUrl;
}
public String getmUserName() {
return mUserName;
}
public void setmUserName(String mUserName) {
this.mUserName = mUserName;
}
public String getmComment() {
return mComment;
}
public void setmComment(String mComment) {
this.mComment = mComment;
}
public String getmImageUrl() {
return mImageUrl;
}
public void setmImageUrl(String mImageUrl) {
this.mImageUrl = mImageUrl;
}
@Exclude
public String getmKey() {
return mKey;
}
@Exclude
public void setmKey(String Key) {
this.mKey = Key;
}
}
To help you build apps with lists, Android provides the RecyclerView . RecyclerView is designed to be very efficient, even with large lists, by reusing, or recycling, the views that have scrolled off the screen.
Pagination with Recyclerview allows the user to see the latest content as page by page. As we load the next 'page' by the time users scroll to the bottom, more content is loaded and available.
Here is Android library to implement Pagination of Firebase Realtime Database in RecyclerView. The Sample app is available in app/ directory that demonstrates feature of this library. Step by step description is given here FirebaseRecyclerPagingation Library binds Firebase Realtime Database Query to a RecyclerView by loading Data in pages.
To support pagination with Firestore database FirebaseUI-Android library has provided the API for that purpose as FirestorePagingAdapter but still, it’s not available for Realtime Database. Firebase Realtime Database is also important in some type of applications such as chatting apps. Because its speed is faster than Firestore.
First of all, go to Firebase Console and create a new Android Project. Download configuration file i.e. google-services.json and place it in the /app directory. In this app, you are showing a paginated list of Posts. Posts will load in RecyclerView.
Pagination is one of the most important factors which helps to reduce the loading time inside our app and increase the performance of our data which is represented in the form of Lists. In this article, we will take a look at adding pagination in our Android RecyclerView .
First you should separate fetching data logic from UI. Then your scroll controller (RecyclerView) should control which images should be called to download (so when it's loaded it should ask for first batch of images, when scroll happens - ask for another batch, etc.). And downloading and caching images is not a trivial task, that's why we have Glide and Coil in Android world.
As a side note please take a look at https://developer.android.com/topic/libraries/architecture/paging/v3-paged-data and https://developer.android.com/topic/libraries/architecture/paging.
Please check what you're adding to the list of mUploads
because every time you add items, you clear the list upfront mUploads.clear();
which may be not what you wanted.
Some notes:
public static List<Upload> mUploads;
mcontext
, Context is already thereHere what you need to do is setLimit
for pagination process.
Here is and example:
private void getUsers(String nodeId) {
Query query;
if (nodeId == null)
query = FirebaseDatabase.getInstance().getReference()
.child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
.orderByKey()
.limitToFirst(mPostsPerPage);
else
query = FirebaseDatabase.getInstance().getReference()
.child(Consts.FIREBASE_DATABASE_LOCATION_USERS)
.orderByKey()
.startAt(nodeId)
.limitToFirst(mPostsPerPage);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
UserModel user;
List<UserModel> userModels = new ArrayList<>();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
userModels.add(userSnapshot.getValue(UserModel.class));
}
mAdapter.addAll(userModels);
mIsLoading = false;
}
@Override
public void onCancelled(DatabaseError databaseError) {
mIsLoading = false;
}
});
}
So here you need to send last node id each time to get new list. After getting response just add your data to ArrayList
or what ever logic you are using. Then just update RecyclerView like this:
blogRecyclerView.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();
totalItems = manager.getItemCount();
scrollOutItems = manager.findFirstVisibleItemPosition();
if (isScrolling && (currentItems + scrollOutItems == totalItems) && nextPage != null) {
isScrolling = false;
progressBar.setVisibility(View.VISIBLE);
getUsers(mlastNodeId);//here your last id will be
}
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With