讓我們跟隨的RecyclerView
源代碼:
@Override
public int computeVerticalScrollOffset() {
return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollOffset(mState) : 0;
}
mLayout是LayoutManager
一個實例。在我們的案例中,它應該屬於StaggeredGridLayoutManager
。讓我們來看看有:
@Override
public int computeVerticalScrollOffset(RecyclerView.State state) {
return computeScrollOffset(state);
}
然後在這裏:
private int computeScrollOffset(RecyclerView.State state) {
if (getChildCount() == 0) {
return 0;
}
ensureOrientationHelper();
return ScrollbarHelper.computeScrollOffset(state, mPrimaryOrientation,
findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
, findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
this, mSmoothScrollbarEnabled, mShouldReverseLayout);
}
最後,我們去ScrollbarHelper.computeScrollOffset:
/**
* @param startChild View closest to start of the list. (top or left)
* @param endChild View closest to end of the list (bottom or right)
*/
static int computeScrollOffset(RecyclerView.State state, OrientationHelper orientation,
View startChild, View endChild, RecyclerView.LayoutManager lm,
boolean smoothScrollbarEnabled, boolean reverseLayout) {
if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null ||
endChild == null) {
return 0;
}
final int minPosition = Math.min(lm.getPosition(startChild),
lm.getPosition(endChild));
final int maxPosition = Math.max(lm.getPosition(startChild),
lm.getPosition(endChild));
final int itemsBefore = reverseLayout
? Math.max(0, state.getItemCount() - maxPosition - 1)
: Math.max(0, minPosition);
if (!smoothScrollbarEnabled) {
return itemsBefore;
}
final int laidOutArea = Math.abs(orientation.getDecoratedEnd(endChild) -
orientation.getDecoratedStart(startChild));
final int itemRange = Math.abs(lm.getPosition(startChild) -
lm.getPosition(endChild)) + 1;
final float avgSizePerRow = (float) laidOutArea/itemRange;
return Math.round(itemsBefore * avgSizePerRow + (orientation.getStartAfterPadding()
- orientation.getDecoratedStart(startChild)));
}
我們應該專注於最後一條語句。此方法返回由項目* avgHeight計算的偏移量,當我們的項目具有各種高度時,這是不準確的。
因此,當我們使用的GridLayoutManager
,由於確認了每一行的高度,所以computeVerticalScrollOffset()
將返回正確的距離。但是,不幸的是,當我們使用StaggeredGridLayoutManager
時,我們無法獲得精確的滾動偏移量。
P.S我知道它不正確的原因,但我不知道如何得到正確的滾動距離。如果有人知道,請訪問:How to get correct scroll distance of RecyclerView when using a StaggeredGridLayoutManager?併發布您的答案。
真棒謝謝 –