private int scrollBy(int dy,RecyclerView.Recycler recycler,RecyclerView.State state){
  int delta=0;
  if (dy > 0) {
    topBorder=getPaddingTop();
    bottomBorder+=dy;
    mCurrentPosition=lastAttachedItemPosition + 1;
    fillGrid(recycler,state,true);
    if (spanBottomMin >= bottomBorder) {
      delta=dy;
      bottomBorder-=dy;
    }
 else {
      bottomBorder=getHeight() - getPaddingBottom();
      if (spanBottomMax - bottomBorder >= dy) {
        delta=dy;
      }
 else {
        delta=Math.max(0,spanBottomMax - bottomBorder);
      }
    }
    offsetChildrenVertical(-delta);
    for (int i=0; i < mSpanCount; i++) {
      spanTop[i]-=delta;
      spanBottom[i]-=delta;
    }
    spanTopMin-=delta;
    spanTopMax-=delta;
    spanBottomMin-=delta;
    spanBottomMax-=delta;
    recycleTopInvisibleViews(recycler);
  }
 else {
    topBorder+=dy;
    bottomBorder=getHeight() - getPaddingBottom();
    if (firstAttachedItemPosition == -1 || firstAttachedItemPosition >= state.getItemCount()) {
      firstAttachedItemPosition=state.getItemCount() - 1;
      lastAttachedItemPosition=firstAttachedItemPosition;
      mCurrentPosition=firstAttachedItemPosition;
    }
 else {
      mCurrentPosition=firstAttachedItemPosition - 1;
    }
    fillGrid(recycler,state,false);
    if (spanTopMax <= topBorder) {
      delta=dy;
      topBorder-=dy;
    }
 else {
      topBorder=getPaddingTop();
      if (spanTopMin - topBorder <= dy) {
        delta=dy;
      }
 else {
        delta=-Math.max(0,topBorder - spanTopMin);
      }
    }
    offsetChildrenVertical(-delta);
    for (int i=0; i < mSpanCount; i++) {
      spanTop[i]-=delta;
      spanBottom[i]-=delta;
    }
    spanTopMin-=delta;
    spanTopMax-=delta;
    spanBottomMin-=delta;
    spanBottomMax-=delta;
    recycleBottomInvisibleViews(recycler);
  }
  scrollOffset+=delta;
  return delta;
}

private int scrollBy ( int dy , RecyclerView . Recycler recycler , RecyclerView . State state ) { int delta = 0 ; if ( dy > 0 ) { topBorder = getPaddingTop ( ) ; bottomBorder += dy ; mCurrentPosition = lastAttachedItemPosition + 1 ; fillGrid ( recycler , state , true ) ; if ( spanBottomMin >= bottomBorder ) { delta = dy ; bottomBorder -= dy ; } else { bottomBorder = getHeight ( ) - getPaddingBottom ( ) ; if ( spanBottomMax - bottomBorder >= dy ) { delta = dy ; } else { delta = Math . max ( 0 , spanBottomMax - bottomBorder ) ; } } offsetChildrenVertical ( - delta ) ; for ( int i = 0 ; i < mSpanCount ; i ++ ) { spanTop [ i ] -= delta ; spanBottom [ i ] -= delta ; } spanTopMin -= delta ; spanTopMax -= delta ; spanBottomMin -= delta ; spanBottomMax -= delta ; recycleTopInvisibleViews ( recycler ) ; } else { topBorder += dy ; bottomBorder = getHeight ( ) - getPaddingBottom ( ) ; if ( firstAttachedItemPosition == - 1 || firstAttachedItemPosition >= state . getItemCount ( ) ) { firstAttachedItemPosition = state . getItemCount ( ) - 1 ; lastAttachedItemPosition = firstAttachedItemPosition ; mCurrentPosition = firstAttachedItemPosition ; } else { mCurrentPosition = firstAttachedItemPosition - 1 ; } fillGrid ( recycler , state , false ) ; if ( spanTopMax <= topBorder ) { delta = dy ; topBorder -= dy ; } else { topBorder = getPaddingTop ( ) ; if ( spanTopMin - topBorder <= dy ) { delta = dy ; } else { delta = - Math . max ( 0 , topBorder - spanTopMin ) ; } } offsetChildrenVertical ( - delta ) ; for ( int i = 0 ; i < mSpanCount ; i ++ ) { spanTop [ i ] -= delta ; spanBottom [ i ] -= delta ; } spanTopMin -= delta ; spanTopMax -= delta ; spanBottomMin -= delta ; spanBottomMax -= delta ; recycleBottomInvisibleViews ( recycler ) ; } scrollOffset += delta ; return delta ; }
the real logic for scroll .
