@Test public void moveGapHandling() throws Throwable { Config config = new Config().spanCount(2).itemCount(40); setupByConfig(config); waitFirstLayout(); mLayoutManager.expectLayouts(2); mAdapter.moveAndNotify(4, 1); mLayoutManager.waitForLayout(2); assertNull("moving item to upper should not cause gaps", mLayoutManager.hasGapsToFix()); }
View hasGapsToFix() { int startChildIndex = 0; int endChildIndex = getChildCount() - 1; BitSet mSpansToCheck = new BitSet(mSpanCount); mSpansToCheck.set(0, mSpanCount, true); final int firstChildIndex, childLimit; final int preferredSpanDir = mOrientation == VERTICAL && isLayoutRTL() ? 1 : -1; if (mShouldReverseLayout) { firstChildIndex = endChildIndex; childLimit = startChildIndex - 1; } else { firstChildIndex = startChildIndex; childLimit = endChildIndex + 1; } final int nextChildDiff = firstChildIndex < childLimit ? 1 : -1; for (int i = firstChildIndex; i != childLimit; i += nextChildDiff) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (mSpansToCheck.get(lp.mSpan.mIndex)) { if (checkSpanForGap(lp.mSpan)) { return child; } mSpansToCheck.clear(lp.mSpan.mIndex); } if (lp.mFullSpan) { continue; } if (i + nextChildDiff != childLimit) { View nextChild = getChildAt(i + nextChildDiff); boolean compareSpans = false; if (mShouldReverseLayout) { int myEnd = mPrimaryOrientation.getDecoratedEnd(child); int nextEnd = mPrimaryOrientation.getDecoratedEnd(nextChild); if (myEnd < nextEnd) { return child; } else if (myEnd == nextEnd) { compareSpans = true; } } else { int myStart = mPrimaryOrientation.getDecoratedStart(child); int nextStart = mPrimaryOrientation.getDecoratedStart(nextChild); if (myStart > nextStart) { return child; } else if (myStart == nextStart) { compareSpans = true; } } if (compareSpans) { LayoutParams nextLp = (LayoutParams) nextChild.getLayoutParams(); if (lp.mSpan.mIndex - nextLp.mSpan.mIndex < 0 != preferredSpanDir < 0) { return child; } } } } return null; }
StaggeredGridLayoutManager extends RecyclerView.LayoutManager implements
        RecyclerView.SmoothScroller.ScrollVectorProvider { View hasGapsToFix() { int startChildIndex = 0; int endChildIndex = getChildCount() - 1; BitSet mSpansToCheck = new BitSet(mSpanCount); mSpansToCheck.set(0, mSpanCount, true); final int firstChildIndex, childLimit; final int preferredSpanDir = mOrientation == VERTICAL && isLayoutRTL() ? 1 : -1; if (mShouldReverseLayout) { firstChildIndex = endChildIndex; childLimit = startChildIndex - 1; } else { firstChildIndex = startChildIndex; childLimit = endChildIndex + 1; } final int nextChildDiff = firstChildIndex < childLimit ? 1 : -1; for (int i = firstChildIndex; i != childLimit; i += nextChildDiff) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (mSpansToCheck.get(lp.mSpan.mIndex)) { if (checkSpanForGap(lp.mSpan)) { return child; } mSpansToCheck.clear(lp.mSpan.mIndex); } if (lp.mFullSpan) { continue; } if (i + nextChildDiff != childLimit) { View nextChild = getChildAt(i + nextChildDiff); boolean compareSpans = false; if (mShouldReverseLayout) { int myEnd = mPrimaryOrientation.getDecoratedEnd(child); int nextEnd = mPrimaryOrientation.getDecoratedEnd(nextChild); if (myEnd < nextEnd) { return child; } else if (myEnd == nextEnd) { compareSpans = true; } } else { int myStart = mPrimaryOrientation.getDecoratedStart(child); int nextStart = mPrimaryOrientation.getDecoratedStart(nextChild); if (myStart > nextStart) { return child; } else if (myStart == nextStart) { compareSpans = true; } } if (compareSpans) { LayoutParams nextLp = (LayoutParams) nextChild.getLayoutParams(); if (lp.mSpan.mIndex - nextLp.mSpan.mIndex < 0 != preferredSpanDir < 0) { return child; } } } } return null; } }
StaggeredGridLayoutManager extends RecyclerView.LayoutManager implements
        RecyclerView.SmoothScroller.ScrollVectorProvider { View hasGapsToFix() { int startChildIndex = 0; int endChildIndex = getChildCount() - 1; BitSet mSpansToCheck = new BitSet(mSpanCount); mSpansToCheck.set(0, mSpanCount, true); final int firstChildIndex, childLimit; final int preferredSpanDir = mOrientation == VERTICAL && isLayoutRTL() ? 1 : -1; if (mShouldReverseLayout) { firstChildIndex = endChildIndex; childLimit = startChildIndex - 1; } else { firstChildIndex = startChildIndex; childLimit = endChildIndex + 1; } final int nextChildDiff = firstChildIndex < childLimit ? 1 : -1; for (int i = firstChildIndex; i != childLimit; i += nextChildDiff) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (mSpansToCheck.get(lp.mSpan.mIndex)) { if (checkSpanForGap(lp.mSpan)) { return child; } mSpansToCheck.clear(lp.mSpan.mIndex); } if (lp.mFullSpan) { continue; } if (i + nextChildDiff != childLimit) { View nextChild = getChildAt(i + nextChildDiff); boolean compareSpans = false; if (mShouldReverseLayout) { int myEnd = mPrimaryOrientation.getDecoratedEnd(child); int nextEnd = mPrimaryOrientation.getDecoratedEnd(nextChild); if (myEnd < nextEnd) { return child; } else if (myEnd == nextEnd) { compareSpans = true; } } else { int myStart = mPrimaryOrientation.getDecoratedStart(child); int nextStart = mPrimaryOrientation.getDecoratedStart(nextChild); if (myStart > nextStart) { return child; } else if (myStart == nextStart) { compareSpans = true; } } if (compareSpans) { LayoutParams nextLp = (LayoutParams) nextChild.getLayoutParams(); if (lp.mSpan.mIndex - nextLp.mSpan.mIndex < 0 != preferredSpanDir < 0) { return child; } } } } return null; } @SuppressWarnings("unused")  StaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes);  StaggeredGridLayoutManager(int spanCount, int orientation); }
StaggeredGridLayoutManager extends RecyclerView.LayoutManager implements
        RecyclerView.SmoothScroller.ScrollVectorProvider { View hasGapsToFix() { int startChildIndex = 0; int endChildIndex = getChildCount() - 1; BitSet mSpansToCheck = new BitSet(mSpanCount); mSpansToCheck.set(0, mSpanCount, true); final int firstChildIndex, childLimit; final int preferredSpanDir = mOrientation == VERTICAL && isLayoutRTL() ? 1 : -1; if (mShouldReverseLayout) { firstChildIndex = endChildIndex; childLimit = startChildIndex - 1; } else { firstChildIndex = startChildIndex; childLimit = endChildIndex + 1; } final int nextChildDiff = firstChildIndex < childLimit ? 1 : -1; for (int i = firstChildIndex; i != childLimit; i += nextChildDiff) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (mSpansToCheck.get(lp.mSpan.mIndex)) { if (checkSpanForGap(lp.mSpan)) { return child; } mSpansToCheck.clear(lp.mSpan.mIndex); } if (lp.mFullSpan) { continue; } if (i + nextChildDiff != childLimit) { View nextChild = getChildAt(i + nextChildDiff); boolean compareSpans = false; if (mShouldReverseLayout) { int myEnd = mPrimaryOrientation.getDecoratedEnd(child); int nextEnd = mPrimaryOrientation.getDecoratedEnd(nextChild); if (myEnd < nextEnd) { return child; } else if (myEnd == nextEnd) { compareSpans = true; } } else { int myStart = mPrimaryOrientation.getDecoratedStart(child); int nextStart = mPrimaryOrientation.getDecoratedStart(nextChild); if (myStart > nextStart) { return child; } else if (myStart == nextStart) { compareSpans = true; } } if (compareSpans) { LayoutParams nextLp = (LayoutParams) nextChild.getLayoutParams(); if (lp.mSpan.mIndex - nextLp.mSpan.mIndex < 0 != preferredSpanDir < 0) { return child; } } } } return null; } @SuppressWarnings("unused")  StaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes);  StaggeredGridLayoutManager(int spanCount, int orientation); @Override boolean isAutoMeasureEnabled(); @Override void onScrollStateChanged(int state); @Override void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler); void setSpanCount(int spanCount); void setOrientation(int orientation); void setReverseLayout(boolean reverseLayout); int getGapStrategy(); void setGapStrategy(int gapStrategy); @Override void assertNotInLayoutOrScroll(String message); int getSpanCount(); void invalidateSpanAssignments(); boolean getReverseLayout(); @Override void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec); @Override void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state); @Override void onLayoutCompleted(RecyclerView.State state); @Override boolean supportsPredictiveItemAnimations(); int[] findFirstVisibleItemPositions(int[] into); int[] findFirstCompletelyVisibleItemPositions(int[] into); int[] findLastVisibleItemPositions(int[] into); int[] findLastCompletelyVisibleItemPositions(int[] into); @Override int computeHorizontalScrollOffset(RecyclerView.State state); @Override int computeVerticalScrollOffset(RecyclerView.State state); @Override int computeHorizontalScrollExtent(RecyclerView.State state); @Override int computeVerticalScrollExtent(RecyclerView.State state); @Override int computeHorizontalScrollRange(RecyclerView.State state); @Override int computeVerticalScrollRange(RecyclerView.State state); @Override void onRestoreInstanceState(Parcelable state); @Override Parcelable onSaveInstanceState(); @Override void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
            RecyclerView.State state, View host, AccessibilityNodeInfoCompat info); @Override void onInitializeAccessibilityEvent(AccessibilityEvent event); @Override int getRowCountForAccessibility(RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override int getColumnCountForAccessibility(RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override void offsetChildrenHorizontal(int dx); @Override void offsetChildrenVertical(int dy); @Override void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount); @Override void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount); @Override void onItemsChanged(RecyclerView recyclerView); @Override void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount); @Override void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount,
            Object payload); @Override boolean canScrollVertically(); @Override boolean canScrollHorizontally(); @Override int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override PointF computeScrollVectorForPosition(int targetPosition); @Override void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
            int position); @Override void scrollToPosition(int position); void scrollToPositionWithOffset(int position, int offset); @Override @RestrictTo(LIBRARY) void collectAdjacentPrefetchPositions(int dx, int dy, RecyclerView.State state,
            LayoutPrefetchRegistry layoutPrefetchRegistry); @SuppressWarnings("deprecation") @Override RecyclerView.LayoutParams generateDefaultLayoutParams(); @Override RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs); @Override RecyclerView.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp); @Override boolean checkLayoutParams(RecyclerView.LayoutParams lp); int getOrientation(); @Nullable @Override View onFocusSearchFailed(View focused, int direction, RecyclerView.Recycler recycler,
            RecyclerView.State state); }
StaggeredGridLayoutManager extends RecyclerView.LayoutManager implements
        RecyclerView.SmoothScroller.ScrollVectorProvider { View hasGapsToFix() { int startChildIndex = 0; int endChildIndex = getChildCount() - 1; BitSet mSpansToCheck = new BitSet(mSpanCount); mSpansToCheck.set(0, mSpanCount, true); final int firstChildIndex, childLimit; final int preferredSpanDir = mOrientation == VERTICAL && isLayoutRTL() ? 1 : -1; if (mShouldReverseLayout) { firstChildIndex = endChildIndex; childLimit = startChildIndex - 1; } else { firstChildIndex = startChildIndex; childLimit = endChildIndex + 1; } final int nextChildDiff = firstChildIndex < childLimit ? 1 : -1; for (int i = firstChildIndex; i != childLimit; i += nextChildDiff) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (mSpansToCheck.get(lp.mSpan.mIndex)) { if (checkSpanForGap(lp.mSpan)) { return child; } mSpansToCheck.clear(lp.mSpan.mIndex); } if (lp.mFullSpan) { continue; } if (i + nextChildDiff != childLimit) { View nextChild = getChildAt(i + nextChildDiff); boolean compareSpans = false; if (mShouldReverseLayout) { int myEnd = mPrimaryOrientation.getDecoratedEnd(child); int nextEnd = mPrimaryOrientation.getDecoratedEnd(nextChild); if (myEnd < nextEnd) { return child; } else if (myEnd == nextEnd) { compareSpans = true; } } else { int myStart = mPrimaryOrientation.getDecoratedStart(child); int nextStart = mPrimaryOrientation.getDecoratedStart(nextChild); if (myStart > nextStart) { return child; } else if (myStart == nextStart) { compareSpans = true; } } if (compareSpans) { LayoutParams nextLp = (LayoutParams) nextChild.getLayoutParams(); if (lp.mSpan.mIndex - nextLp.mSpan.mIndex < 0 != preferredSpanDir < 0) { return child; } } } } return null; } @SuppressWarnings("unused")  StaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes);  StaggeredGridLayoutManager(int spanCount, int orientation); @Override boolean isAutoMeasureEnabled(); @Override void onScrollStateChanged(int state); @Override void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler); void setSpanCount(int spanCount); void setOrientation(int orientation); void setReverseLayout(boolean reverseLayout); int getGapStrategy(); void setGapStrategy(int gapStrategy); @Override void assertNotInLayoutOrScroll(String message); int getSpanCount(); void invalidateSpanAssignments(); boolean getReverseLayout(); @Override void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec); @Override void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state); @Override void onLayoutCompleted(RecyclerView.State state); @Override boolean supportsPredictiveItemAnimations(); int[] findFirstVisibleItemPositions(int[] into); int[] findFirstCompletelyVisibleItemPositions(int[] into); int[] findLastVisibleItemPositions(int[] into); int[] findLastCompletelyVisibleItemPositions(int[] into); @Override int computeHorizontalScrollOffset(RecyclerView.State state); @Override int computeVerticalScrollOffset(RecyclerView.State state); @Override int computeHorizontalScrollExtent(RecyclerView.State state); @Override int computeVerticalScrollExtent(RecyclerView.State state); @Override int computeHorizontalScrollRange(RecyclerView.State state); @Override int computeVerticalScrollRange(RecyclerView.State state); @Override void onRestoreInstanceState(Parcelable state); @Override Parcelable onSaveInstanceState(); @Override void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
            RecyclerView.State state, View host, AccessibilityNodeInfoCompat info); @Override void onInitializeAccessibilityEvent(AccessibilityEvent event); @Override int getRowCountForAccessibility(RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override int getColumnCountForAccessibility(RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override void offsetChildrenHorizontal(int dx); @Override void offsetChildrenVertical(int dy); @Override void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount); @Override void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount); @Override void onItemsChanged(RecyclerView recyclerView); @Override void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount); @Override void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount,
            Object payload); @Override boolean canScrollVertically(); @Override boolean canScrollHorizontally(); @Override int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
            RecyclerView.State state); @Override PointF computeScrollVectorForPosition(int targetPosition); @Override void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
            int position); @Override void scrollToPosition(int position); void scrollToPositionWithOffset(int position, int offset); @Override @RestrictTo(LIBRARY) void collectAdjacentPrefetchPositions(int dx, int dy, RecyclerView.State state,
            LayoutPrefetchRegistry layoutPrefetchRegistry); @SuppressWarnings("deprecation") @Override RecyclerView.LayoutParams generateDefaultLayoutParams(); @Override RecyclerView.LayoutParams generateLayoutParams(Context c, AttributeSet attrs); @Override RecyclerView.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp); @Override boolean checkLayoutParams(RecyclerView.LayoutParams lp); int getOrientation(); @Nullable @Override View onFocusSearchFailed(View focused, int direction, RecyclerView.Recycler recycler,
            RecyclerView.State state); static final int HORIZONTAL; static final int VERTICAL; static final int GAP_HANDLING_NONE; @SuppressWarnings("unused")
    @Deprecated
    static final int GAP_HANDLING_LAZY; static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS; }