Search code examples
androidandroid-recyclerviewscreennestedscrollview

RecyclerView ViewHolder creation inside NestedScrollView


I have two problems caused by the same source. I'm working on a social media app, I have a profile view containing a CollapsingToolbarLayout for the profile picture and RecyclerView inside a NestedScrollView for the posts feed.

The behaviour I didn't expect is that let's say I have 20 posts in the RecyclerView and the screen can only display 3, the recycler adapter creates 20 view holders and they are all considered as visible.

This causes two problems for me : 1 - The posts may contain videos and I want the video to be stopped if the post is not visible on the screen. I used to do this on my other RecyclerViews.

@Override
public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
    if (holder instanceof PostViewHolder) {
        PostViewHolder postViewHolder = (PostViewHolder) holder;
        pauseVideo(postViewHolder.videoPlayer);
    }
}

This method is never called because the RecyclerView or adapter or whatever considers all the view holders to be visible on the screen. To make sure my assumption is correct I did a log on onViewAttachedToWindow and if the list contains 20 posts, it gets called 20 times when I add the list to the RecyclerView.

2 - I want posts to be loaded dynamically (load small batches on scroll). This was achieved using this method :

WrapContentLinearLayoutManager llManager = new WrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(llManager);

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if(dy > 0) { //check for scroll down
            if (llManager.findFirstVisibleItemPosition() + 10 > llManager.getItemCount() && !loadingMorePosts) {
                loadingMorePosts = true;
                dbListeners.getMoreUserPosts();
            }
        }
    }
});

This doesn't work too because llManager.findFirstVisibleItemPosition() always returns 0.

Am I doing something wrong or is this the expected behaviour from a RecyclerView inside a nested ScrollView? And is there a solution or a workaround for the second problem because loading all the posts at once is not acceptable.

And Thanks.


Solution

  • You have to handle pagination at scroll listener of nesterscroll view

     nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView view, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                if (scrollY == (view.getChildAt(0).getMeasuredHeight() - view.getMeasuredHeight())&& !loadingMorePosts) {
                    loadingMorePosts = true;
                    dbListeners.getMoreUserPosts();
                }
    
            }
        });