SoFunction
Updated on 2025-03-01

Detailed explanation of the method of obtaining the sliding distance of RecyclerView on Android

Let’s talk about the ultimate solution that can be used first. Everyone is anxious to copy it directly. If you want to know about it, come and see it later.

There is no header and all Items are highly consistent

    private fun getScrollYDistance(recyclerView: RecyclerView): Int? {
         {
            val layoutManager =  as LinearLayoutManager
            val position = ()
            val firstVisibleChildView = (position)
            val itemHeight = firstVisibleChildView!!.height
            return position * itemHeight - 
        }
        return null
    }

There is a header, and all other Items are highly consistent

    var headerHeight = 0
    private fun getScrollYDistance(recyclerView: RecyclerView): Int? {
         {
            val layoutManager =  as LinearLayoutManager
            val position = ()
            if (position == 0) {
                val headerView = (0)
                headerHeight = headerView!!.height
            }
            val firstVisibleChildView = (position)
            val itemHeight = firstVisibleChildView!!.height
            return if (position == 0) {
                position * itemHeight - 
            } else {
                (position - 1) * itemHeight -  + headerHeight
            }
        }
        return null
    }

There are multiple headers, and other Items are consistent

   Integer[] headerHeightArray;
    private int getScollYDistance(){
        LinearLayoutManager layoutManager = (LinearLayoutManager) ().getLayoutManager();
        // Get the location of the first visible item        int position = ();
        // Get the first visible item        View firstVisiableChildView = (position);
        // It is necessary to consider whether there is a header to save the height of all headers        int headerCount = ();
        if (headerCount > 0) {
            if (headerHeightArray == null) {
                headerHeightArray = new Integer[headerCount];
            }
            if (position < headerCount) {
                View headerView_i = (position);
                headerHeightArray[position] = headerView_i.getHeight();
            }
        }
        // Get the height of the first visible item        int itemHeight = ();
        // Get the location of the first visible item        int distance = 0;
        if (position == 0) {
            distance = position * itemHeight - ();
        } else {
            int allHeaderHeight = 0;
            for (int i = 0; i < (position,headerCount); i++) {
                allHeaderHeight = allHeaderHeight + headerHeightArray[i];
            }
            distance = (position - (position,headerCount)) * itemHeight - () + allHeaderHeight;
        }
        return distance;
    }

Pay attention to the call location:

(new () {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    (recyclerView, dx, dy);
                    getScollYDistance();
                }
            });

Some of the ideas I tried have some problems, some can be compensated, and some can be finished directly

Although RecyclerView has getScrollX() and getScrollY(), the test found that these two functions always return 0, which is too speechless. Therefore, the following methods have been thought of to obtain the sliding distance:

Using OnScrollListener

        (new () {
            private int totalDy = ;
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                totalDy -= dy;
            }
        });

As stated in the code, totalDy ensures that the sliding distance of the RecyclerView is stored, but when I slide down the RecyclerView and then insert/delete/moves the Item, totalDy becomes inaccurate; for example, delete or insert a new Item, then totalDy cannot return to 0. This can be used to add or subtract totalDy by adding or subtracting the corresponding height when deleting or inserting.

totalDy = ();

However, the compute method does not calculate the exact distance of the sliding. There is an answer on * that explains that it is the average height of the item * the visible number of items, which is not the exact distance we need.

totalDy = ().getTop();

The animation is set by the sliding distance of the first item, but the totalDy obtained by this method is cleared after sliding to a certain level.

This is because (0) returns always the first visible child, not the first child of all view lists, so this usage does not get the sliding distance.

In addition, the following three usages are equivalent, and they all obtain the first visible child:

       LinearLayoutManager layoutManager = (LinearLayoutManager) ();
       View firstVisiableChildView = ();
       View firstVisiableChildView = ()
       int position = ();
       View firstVisiableChildView = (position)

But the following is not to get the first visible child, but to get the first child of all view lists. But after sliding for a distance, it always returns null, that is, after the first child is recycled, it always returns null.

//Don't use this function to get the first item, it will return null when the first item is recycled.
LinearLayoutManager layoutManager = (LinearLayoutManager) ();
View child2 = ();

This is the article about the detailed explanation of the sliding distance method of Android to obtain RecyclerView. For more related content on Android to obtain RecyclerView, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!