protected int fill(RecyclerView.Recycler recycler, LayoutState layoutState,
                       RecyclerView.State state, boolean stopOnFocusable) {
        // max offset we should set is mFastScroll + available
        final int start = layoutState.mAvailable;
        if (layoutState.mScrollingOffset != LayoutState.SCOLLING_OFFSET_NaN) {
            // TODO ugly bug fix. should not happen
            if (layoutState.mAvailable < 0) {
                layoutState.mScrollingOffset += layoutState.mAvailable;
            }
            recycleByLayoutStateExpose(recycler, layoutState);
        }
        int remainingSpace = layoutState.mAvailable + layoutState.mExtra + recycleOffset;
        while (remainingSpace > 0 && layoutState.hasMore(state)) {
            layoutChunkResultCache.resetInternal();
            layoutChunk(recycler, state, layoutState, layoutChunkResultCache);
            if (layoutChunkResultCache.mFinished) {
                break;
            }
            layoutState.mOffset += layoutChunkResultCache.mConsumed * layoutState.mLayoutDirection;
            /**
             * Consume the available space if:
             * * layoutChunk did not request to be ignored
             * * OR we are laying out scrap children
             * * OR we are not doing pre-layout
             */
            if (!layoutChunkResultCache.mIgnoreConsumed || mLayoutState.mScrapList != null
                    || !state.isPreLayout()) {
                layoutState.mAvailable -= layoutChunkResultCache.mConsumed;
                // we keep a separate remaining space because mAvailable is important for recycling
                remainingSpace -= layoutChunkResultCache.mConsumed;
            }

            if (layoutState.mScrollingOffset != LayoutState.SCOLLING_OFFSET_NaN) {
                layoutState.mScrollingOffset += layoutChunkResultCache.mConsumed;
                if (layoutState.mAvailable < 0) {
                    layoutState.mScrollingOffset += layoutState.mAvailable;
                }
                recycleByLayoutStateExpose(recycler, layoutState);
            }
            if (stopOnFocusable && layoutChunkResultCache.mFocusable) {
                break;
            }
        }
        if (DEBUG) {
            validateChildOrderExpose();
        }
        return start - layoutState.mAvailable;
    }
protected int fill ( RecyclerView . Recycler recycler , LayoutState layoutState , RecyclerView . State state , boolean stopOnFocusable ) { final int start = layoutState . mAvailable ; if ( layoutState . mScrollingOffset != LayoutState . SCOLLING_OFFSET_NaN ) { if ( layoutState . mAvailable < 0 ) { layoutState . mScrollingOffset += layoutState . mAvailable ; } recycleByLayoutStateExpose ( recycler , layoutState ) ; } int remainingSpace = layoutState . mAvailable + layoutState . mExtra + recycleOffset ; while ( remainingSpace > 0 && layoutState . hasMore ( state ) ) { layoutChunkResultCache . resetInternal ( ) ; layoutChunk ( recycler , state , layoutState , layoutChunkResultCache ) ; if ( layoutChunkResultCache . mFinished ) { break ; } layoutState . mOffset += layoutChunkResultCache . mConsumed * layoutState . mLayoutDirection ; if ( ! layoutChunkResultCache . mIgnoreConsumed || mLayoutState . mScrapList != null || ! state . isPreLayout ( ) ) { layoutState . mAvailable -= layoutChunkResultCache . mConsumed ; remainingSpace -= layoutChunkResultCache . mConsumed ; } if ( layoutState . mScrollingOffset != LayoutState . SCOLLING_OFFSET_NaN ) { layoutState . mScrollingOffset += layoutChunkResultCache . mConsumed ; if ( layoutState . mAvailable < 0 ) { layoutState . mScrollingOffset += layoutState . mAvailable ; } recycleByLayoutStateExpose ( recycler , layoutState ) ; } if ( stopOnFocusable && layoutChunkResultCache . mFocusable ) { break ; } } if ( DEBUG ) { validateChildOrderExpose ( ) ; } return start - layoutState . mAvailable ; }
The magic functions :). Fills the given layout, defined by the layoutState. This is fairly
independent from the rest of the {@link LinearLayoutManager}
and with little change, can be made publicly available as a helper class.

@param recycler        Current recycler that is attached to RecyclerView
@param layoutState     Configuration on how we should fill out the available space.
@param state           Context passed by the RecyclerView to control scroll steps.
@param stopOnFocusable If true, filling stops in the first focusable new child
@return Number of pixels that it added. Useful for scoll functions.