@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();
}

@ 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 ( ) ; }
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 .
