1

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

        }


        }
    }
Vasant Raval
  • 257
  • 1
  • 12
  • 31
  • are you using full resolution images in your recycleview or thumbnails? – quealegriamasalegre Oct 25 '21 at 00:16
  • 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. – quealegriamasalegre Oct 25 '21 at 00:25
  • I'm not using thumbnail right now, so yes it the image are full resolution, and some of them are even 2k resolution image – Vasant Raval Oct 25 '21 at 04:56

1 Answers1

1

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.

quealegriamasalegre
  • 2,887
  • 1
  • 13
  • 35
  • I have added the adapter class please can you check it, please – Vasant Raval Oct 25 '21 at 04:50
  • "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. " actually, I'm a beginner in this so just trying different solutions i get from different sources, – Vasant Raval Oct 25 '21 at 05:06
  • 1
    Im editing my answer so its easier to read – quealegriamasalegre Oct 25 '21 at 05:27
  • ok i have tried it but still the images are not showing up – Vasant Raval Oct 25 '21 at 05:38
  • by the I'm having a fragment not an activity just in case – Vasant Raval Oct 25 '21 at 05:39
  • it should not matter that its a fragment. i just noticed that you only call getData() in your onscroll listener. maybe try calling it onCreate() – quealegriamasalegre Oct 25 '21 at 05:43
  • should I use thumbnail, I actually wondered what Instagram and other apps do when the images are still loading do they use a thumbmnail or something else – Vasant Raval Oct 25 '21 at 05:43
  • In order to debug I recommend that you try inflating your recyclerview with some dummy images first. you can put them in the raw folder in resources and create a fake mUploads array. once that works we will know that any remaining issues stem from your getData() method – quealegriamasalegre Oct 25 '21 at 05:46
  • ok I have added getData(); just before onscrollListner while still remaining inside onscroll too ,the images are loading but don't know is it working like an endless scroll or just because i have added getData before onScroll it just loads all images at once in the adapter – Vasant Raval Oct 25 '21 at 05:48
  • I think instagram uses thumbnails or blurred out pixel matrices while images load. but not sure – quealegriamasalegre Oct 25 '21 at 05:48
  • but yes there is some difference in loading images , where can I add a progress bar so I can know that images are loading like endless scroll or just all at once – Vasant Raval Oct 25 '21 at 05:50
  • I dont know how your database works but yess the onDatasetChanged method should be doing its thing. I dont think you have to call getData() more than once. I think what you have to do is request new data from firebase once you scroll but im not sure how to do that. I know more about recyclerview than about firebase – quealegriamasalegre Oct 25 '21 at 05:54
  • I want the first 10 images should load in the adapter and when the scroll out items reaches 5 next 5 images loads up in the adapter, so I'm trying to say that adapter will maintain 10 images in it – Vasant Raval Oct 25 '21 at 05:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238495/discussion-between-quealegriamasalegre-and-vasant-raval). – quealegriamasalegre Oct 25 '21 at 05:59
  • watch this video it might help you https://www.youtube.com/watch?v=jIGxgA_wHvg – quealegriamasalegre Oct 25 '21 at 06:34