androidandroid-recyclerviewpaginationinfinite-scrollendlessscroll

Images are not showing up (loading) in recyclerview after implementing Endless scroll (Pagination)


I have implemented an EndlessScroll for RecyclerView (Only Images in it) or we can say Pagination but after implementing it I don't know why the images are not loading up from Firebase

So I tried to include a placeholder image from my adapter class but the default placeholder image is not showng up too

BTW before asking this SO Q I asked a Q to how to implement Pagination with StaggeredGridLayoutManager but after implementing the answer to my Orignal question there are no errors but the images are showing up This is the Question link for reference on how I implemented the pagination in my recycler view - How to implement endless scroll (pagination) in recyclerview with StaggeredGridLayoutManager

Here is the code

Home_Fragment.java // for those who are referencing my original question which I put a link above,this is a different fragment than my original question in the original question I have included Profile_Fragment.java, but because that file is much longer,I have included this because it has less code compared to the orignal

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

        StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
        postRecyclerView.setLayoutManager(
                staggeredGridLayoutManager // I have 3 rows
        );


        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();
                    }
                }
            }
        });
//        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() {
            @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);


                    }

                }

                //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 static class PostViewHolder extends RecyclerView.ViewHolder {

        private final ShapeableImageView imageView;

        public PostViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imagePostHome);

        }


        }
    }

Solution

  • I think you neen something like postsAdapter.setUploads(mUploads) to reset them in the adapter before you call postsAdapter.notifyDataSetChanged(); because its not clear to me how your adapter is processing mUploads as you are only passing it once in the constructor. I dont think passing mUploads to the adapters constructor will keep a pointer to the original object.

    Ideally you would put mUploads inside the adapter class and only modify its contents through methods like . setUploads(), addUploads() etc.

    EDIT

    so basically I recommend you add the following method to your adapter class:

    public void setUploads(List<Upload> uploads){
       mUploads=uploads;
    }
    

    then in your activity call postsAdapter.setUploads(mUploads); just before you call

    //notify the adapter
    postsAdapter.notifyDataSetChanged();
    

    try it out and let me know.

    Regarding your use of full images let me tell you this will cause you trouble. I used to do the same thing and not only will your images take quite a while to load but also your recyclerview will not move smoothly unless you want your app to only be usable in the most high end phones. I recommend you store some acceptably small versions of your photos in firebase, they dont have to be thumbnails but definitely less than 1 megapixel. its best to try different resolutions and see what works best on an array of different devices. Even then you might want to put a loading spinner or a dummy image in while your photos render.