private void updateHeaderPositions(RecyclerView.Recycler recycler) {

        // first, for each section represented by the current list of items,
        // ensure that the header for that section is extant

        Set<Integer> visitedSections = new HashSet<>();
        for (int i = 0, n = getChildCount(); i < n; i++) {
            View view = getChildAt(i);
            int sectionIndex = getViewSectionIndex(view);
            if (visitedSections.add(sectionIndex)) {
                if (adapter.doesSectionHaveHeader(sectionIndex)) {
                    createSectionHeaderIfNeeded(recycler, sectionIndex);
                }
            }
        }

        // header is always positioned at top
        int left = getPaddingLeft();
        int right = getWidth() - getPaddingRight();

        for (View headerView : headerViews) {
            int sectionIndex = getViewSectionIndex(headerView);

            // find first and last non-header views in this section
            View ghostHeader = null;
            View firstViewInNextSection = null;
            for (int i = 0, n = getChildCount(); i < n; i++) {
                View view = getChildAt(i);

                // the view has been recycled
                if (isViewRecycled(view)) {
                    continue;
                }

                int type = getViewBaseType(view);
                if (type == SectioningAdapter.TYPE_HEADER) {
                    continue;
                }

                int viewSectionIndex = getViewSectionIndex(view);
                if (viewSectionIndex == sectionIndex) {
                    if (type == SectioningAdapter.TYPE_GHOST_HEADER) {
                        ghostHeader = view;
                    }
                } else if (viewSectionIndex == sectionIndex + 1) {
                    if (firstViewInNextSection == null) {
                        firstViewInNextSection = view;
                    }
                }
            }

            int height = getDecoratedMeasuredHeight(headerView);
            int top = getPaddingTop();

            // initial position mark
            HeaderPosition headerPosition = HeaderPosition.STICKY;

            if (ghostHeader != null) {
                int ghostHeaderTop = getDecoratedTop(ghostHeader);
                if (ghostHeaderTop >= top) {
                    top = ghostHeaderTop;
                    headerPosition = HeaderPosition.NATURAL;
                }
            }

            if (firstViewInNextSection != null) {
                int nextViewTop = getDecoratedTop(firstViewInNextSection);
                if (nextViewTop - height < top) {
                    top = nextViewTop - height;
                    headerPosition = HeaderPosition.TRAILING;
                }
            }

            // now bring header to front of stack for overlap, and position it
            headerView.bringToFront();
            layoutDecorated(headerView, left, top, right, top + height);

            // notify adapter of positioning for this header
            recordHeaderPositionAndNotify(sectionIndex, headerView, headerPosition);
        }
    }
Updates firstViewAdapterPosition to the adapter position  of the highest item in the list - e.g., the
adapter position of the item with lowest y value in the list

@return the y value of the topmost view in the layout, or paddingTop if empty
android/modules/module_common/src/main/java/github/tornaco/android/thanos/widget/section/StickyHeaderLayoutManager.java