Home:ALL Converter>Recyclerview StaggeredGridLayoutManager - Find last visible item

Recyclerview StaggeredGridLayoutManager - Find last visible item

Ask Time:2017-03-22T18:17:37         Author:Vamsi Challa

Json Formatter

I am using a Recyclerview with StaggeredGridLayoutManager with Endless Scroll. I want to do a network call when the last item of the list is visible to the user. So here is my code:

   public RecyclerViewAdapter(Context context) {

            Log.d(Const.DEBUG, "RecyclerViewAdapter Constructor()");

            this.context = context;

            final StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) recyclerView.getLayoutManager();

            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);

                    totalItemCount = staggeredGridLayoutManager.getItemCount();
                    lastVisibleItems = staggeredGridLayoutManager.findLastVisibleItemPositions(new int[mStaggeredLayoutManager.getSpanCount()]);

                    Log.d(Const.DEBUG, "LastVisibleItems: " + Arrays.toString(lastVisibleItems));
                    Log.d(Const.DEBUG, "LastVisibleItems Count: " + lastVisibleItems.length);

                    if (staggeredGridLayoutManager.getSpanCount() == 1) {
                        lastVisibleItem = lastVisibleItems[0];
                    } else if (staggeredGridLayoutManager.getSpanCount() == 2) {
                        lastVisibleItem = Math.max(lastVisibleItems[0], lastVisibleItems[1]);
                    } else if (staggeredGridLayoutManager.getSpanCount() == 3) {
                        lastVisibleItem = Math.max(Math.max(lastVisibleItems[0], lastVisibleItems[1]), lastVisibleItems[2]);
                    }


                    if (!isRefreshing && (totalItemCount <= lastVisibleItem + visibleThreshold)) {

                        Log.d(Const.DEBUG, "isRefreshing: " + isRefreshing);
                        Log.d(Const.DEBUG, "totalItemCount: " + totalItemCount);
                        Log.d(Const.DEBUG, "lastVisibileItem: " + lastVisibleItem);
                        Log.d(Const.DEBUG, "visibileThreshold: " + visibleThreshold);

                        Log.d(Const.DEBUG, "calling LoadMore()");

                        if (mIOnLoadMoreListener != null) {
                            mIOnLoadMoreListener.onLoadMore();
                        }

                        isRefreshing = true;
                    }
                }
            });

        }

I get 9 values from server on first call. So, when i move to the last index[8], the lastVisibleItem will be 8 and visibleThreshold is 1, totalItemCount is 9 and so the next network call should happen. What is actually happening now, is, when the screen loads for the first time, the lastVisibleItem should be 1 or 2, but its returning 8, and as a result, the loadMore() is getting called.

Logcat:

D/xx: Items Count: 9
D/xx: LastVisibleItems: [8]
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: LastVisibleItems Count: 1
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: isRefreshing: false
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: totalItemCount: 9
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: lastVisibileItem: 8
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: visibileThershold: 1
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: calling LoadMore()
03-22 15:22:52.772 5957-5957/codsiga.com.xx D/xx: onLoadMore()
03-22 15:22:52.798 5957-5957/codsiga.com.xx D/xx: getDataFromServer()

What is wrong in the above code? Let me know if you need anything else. The same code worked well before.

Author:Vamsi Challa,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/42948667/recyclerview-staggeredgridlayoutmanager-find-last-visible-item
Sachin Varma :

Try this.\n\n private int pastVisiblesItems, visibleItemCount, totalItemCount;\n private boolean loading = true; \n private StaggeredGridLayoutManager layoutManager;\n private RecyclerView recyclerView ;\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.activity_main);\n layoutManager=new StaggeredGridLayoutManager(2,1);\n recyclerView = (RecyclerView) findViewById(R.id.recycler_view); \n recyclerView.setLayoutManager(layoutManager);\n recycleView.addOnScrollListener(new RecyclerView.OnScrollListener() {\n @Override\n public void onScrolled(RecyclerView recyclerView, int dx, int dy) {\n\n if (dy > 0) //for vertical scrolling\n {\n\n } else if (dy < 0) {\n\n }\n if (dx > 0)//for horizontal scrolling\n {\n visibleItemCount = layoutManager.getChildCount();\n totalItemCount = layoutManager.getItemCount();\n pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();\n\n if (loading) {\n if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {\n loading = false; \n loadMore(); //desired function call \n }\n }\n } \n }\n });\n }\n\n\nPlease don't forget to make loading=true after the success of API calling.\n\nHope it may help..",
2017-03-22T10:43:40
Vishal Nagvadiya :

following code is work for me :\n\n//return true if it's last item visited\n private boolean isLastItemDisplaying(RecyclerView recyclerView) {\n if (recyclerView.getAdapter().getItemCount() != 0) {\n //int lastVisibleItemPosition = ((StaggeredGridLayoutManager)recyclerView.getLayoutManager()).findLastVisibleItemPositions();\n int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) Objects.requireNonNull(recyclerView.getLayoutManager())).findLastVisibleItemPositions(null);\n // get maximum element within the list\n int lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);\n return lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1;\n }\n return false;\n}\n\n\n\n//get last item\npublic int getLastVisibleItem(int[] lastVisibleItemPositions) {\n int maxSize = 0;\n for (int i = 0; i < lastVisibleItemPositions.length; i++) {\n if (i == 0) {\n maxSize = lastVisibleItemPositions[i];\n } else if (lastVisibleItemPositions[i] > maxSize) {\n maxSize = lastVisibleItemPositions[i];\n }\n }\n return maxSize;\n}\n",
2019-08-06T07:42:02
yy