question: @ Override public void onLayoutChildren ( RecyclerView . Recycler recycler , RecyclerView . State state ) { if ( state . getItemCount ( ) == 0 ) { detachAndScrapAttachedViews ( recycler ) ; return ; } if ( state . isPreLayout ( ) ) { if ( getChildCount ( ) == 0 ) return ; final int childCount = getChildCount ( ) ; for ( int i = 0 ; i < childCount ; i ++ ) { View child = getChildAt ( i ) ; RecyclerView . LayoutParams lp = ( RecyclerView . LayoutParams ) child . getLayoutParams ( ) ; if ( lp . isItemRemoved ( ) ) { removedTopAndBoundPositionCount ++ ; if ( firstChangedPosition == - 1 || firstAttachedItemPosition + i < firstChangedPosition ) { firstChangedPosition = firstAttachedItemPosition + i ; } } } if ( removedTopAndBoundPositionCount != 0 ) { layoutAttachedAndAppearingViews ( recycler , state ) ; } isBeforePreLayout = false ; return ; } if ( getChildCount ( ) == 0 ) { initializeLayoutParameters ( ) ; fillGrid ( recycler , state , true ) ; return ; } if ( isNotifyDataSetChanged ) { detachAndScrapAttachedViews ( recycler ) ; initializeLayoutParameters ( ) ; fillGrid ( recycler , state , true ) ; isNotifyDataSetChanged = false ; return ; } if ( firstChangedPosition == - 1 ) { mCurrentPosition = firstAttachedItemPosition ; lastAttachedItemPosition = firstAttachedItemPosition ; topBorder = getPaddingTop ( ) ; bottomBorder = getHeight ( ) - getPaddingBottom ( ) ; spanBottom = Arrays . copyOf ( spanTop , mSpanCount ) ; updateSpanBottomParameters ( ) ; detachAndScrapAttachedViews ( recycler ) ; fillGrid ( recycler , state , true ) ; isBeforePreLayout = true ; return ; } for ( int i = firstChangedPosition ; i < state . getItemCount ( ) ; i ++ ) { if ( itemLayoutWidthCache . get ( i , 0 ) != 0 ) { itemLayoutWidthCache . delete ( i ) ; itemLayoutHeightCache . delete ( i ) ; itemOccupiedStartSpan . delete ( i ) ; } if ( fakeItemLayoutWidthCache . get ( i , 0 ) != 0 ) { itemLayoutWidthCache . put ( i , fakeItemLayoutWidthCache . get ( i ) ) ; itemLayoutHeightCache . put ( i , fakeItemLayoutHeightCache . get ( i ) ) ; itemOccupiedStartSpan . put ( i , fakeItemOccupiedStartSpan . get ( i ) ) ; } } fakeItemLayoutWidthCache . clear ( ) ; fakeItemLayoutHeightCache . clear ( ) ; fakeItemOccupiedStartSpan . clear ( ) ; detachAndScrapAttachedViews ( recycler ) ; if ( firstChangedPosition < firstAttachedItemPosition ) { mCurrentPosition = firstAttachedItemPosition ; lastAttachedItemPosition = firstAttachedItemPosition ; topBorder = getPaddingTop ( ) ; bottomBorder = getHeight ( ) - getPaddingBottom ( ) ; spanBottom = Arrays . copyOf ( spanTop , mSpanCount ) ; updateSpanBottomParameters ( ) ; fillGrid ( recycler , state , true ) ; if ( spanBottomMax < bottomBorder ) { scrollBy ( spanBottomMax - bottomBorder , recycler , state ) ; } layoutDisappearingViews ( recycler , state ) ; } else { mCurrentPosition = firstAttachedItemPosition ; lastAttachedItemPosition = firstAttachedItemPosition ; topBorder = getPaddingTop ( ) ; bottomBorder = getHeight ( ) - getPaddingBottom ( ) ; spanBottom = Arrays . copyOf ( spanTop , mSpanCount ) ; updateSpanBottomParameters ( ) ; fillGrid ( recycler , state , true ) ; if ( spanBottomMax - bottomBorder < 0 ) { scrollBy ( spanBottomMax - bottomBorder , recycler , state ) ; } } isBeforePreLayout = true ; firstChangedPosition = - 1 ; removedTopAndBoundPositionCount = 0 ; disappearingViewCache . clear ( ) ; }
target:  Called when it is initial layout, or the data set is changed. If supportsPredictiveItemAnimations() returns true, it will be called twice, i.e., the pre-layout and the real layout.