通过使用as的Profiler监听cpu的运行状况,我们可以更容易的了解到Recycleview滑动的执行过程。由下图可以看到,recycle view的滑动一次调用了:
1 2 3 4 5 6 7 8 9
| RecyclerView.onTouchEvent() RecyclerView.scrollByInternal() RecyclerView.scrollStep() LinearLayoutManager.scrollVerticallyBy() LinearLayoutManager.scrollBy() OrientationHelper.offsetChildren() LayoutManager.offsetChildrenVertical() RecyclerView.offsetChildrenVertical() View.offsetTopAndBottom()
|
获取Recycleview滑了多少距离得一个好方式:
1 2 3 4 5 6 7
| public int getScollYDistance() { LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager(); int position = layoutManager.findFirstVisibleItemPosition(); View firstVisiableChildView = layoutManager.findViewByPosition(position); int itemHeight = firstVisiableChildView.getHeight(); return (position) * itemHeight - firstVisiableChildView.getTop(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| void scrollStep(int dx, int dy, @Nullable int[] consumed) { startInterceptRequestLayout(); onEnterLayoutOrScroll();
TraceCompat.beginSection(TRACE_SCROLL_TAG); fillRemainingScrollValues(mState);
int consumedX = 0; int consumedY = 0; if (dx != 0) { consumedX = mLayout.scrollHorizontallyBy(dx, mRecycler, mState); } if (dy != 0) { consumedY = mLayout.scrollVerticallyBy(dy, mRecycler, mState); }
TraceCompat.endSection(); repositionShadowingViews();
onExitLayoutOrScroll(); stopInterceptRequestLayout(false);
if (consumed != null) { consumed[0] = consumedX; consumed[1] = consumedY; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @Override public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { if (mOrientation == HORIZONTAL) { return 0; } return scrollBy(dy, recycler, state); } int scrollBy(int delta, RecyclerView.Recycler recycler, RecyclerView.State state) { if (getChildCount() == 0 || delta == 0) { return 0; } ensureLayoutState(); mLayoutState.mRecycle = true; final int layoutDirection = delta > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START; final int absDelta = Math.abs(delta); updateLayoutState(layoutDirection, absDelta, true, state); final int consumed = mLayoutState.mScrollingOffset + fill(recycler, mLayoutState, state, false); if (consumed < 0) { return 0; } final int scrolled = absDelta > consumed ? layoutDirection * consumed : delta; mOrientationHelper.offsetChildren(-scrolled); mLayoutState.mLastScrollDelta = scrolled; return scrolled; }
|