@Overridepublicvoidrun() {
...省略部分代码
finalOverScrollerscroller= mScroller;
//获得layoutManger中的SmoothScrollerfinalSmoothScrollersmoothScroller= mLayout.mSmoothScroller;
if (scroller.computeScrollOffset()) {//如果是第一次走,会返回false
...省略部分代码
if (smoothScroller != null) {
if (smoothScroller.isPendingInitialRun()) {
smoothScroller.onAnimation(0, 0);
if (!mReSchedulePostAnimationCallback) {
smoothScroller.stop(); //stop if it does not trigger any scroll
...省略部分代码
复制代码
if (smoothScroller != null) {
if (smoothScroller.isPendingInitialRun()) {
smoothScroller.onAnimation(0, 0);
if (!mReSchedulePostAnimationCallback) {
smoothScroller.stop(); //stop if it does not trigger any scroll复制代码
最后发现,只是走了一个onAnimation(0,0),继续走该方法。
private void onAnimation(int dx, int dy) {
final RecyclerView recyclerView = mRecyclerView;
if (!mRunning || mTargetPosition == RecyclerView.NO_POSITION || recyclerView == null) {
stop();
mPendingInitialRun = false;
if (mTargetView != null) {//判断目标视图是否存在,如果存在则计算移动到位置需要移动的距离
if (getChildPosition(mTargetView) == mTargetPosition) {
onTargetFound(mTargetView, recyclerView.mState, mRecyclingAction);
mRecyclingAction.runIfNecessary(recyclerView);
stop();
} else {
Log.e(TAG, "Passed over target position while smooth scrolling.");
mTargetView = null;
if (mRunning) {//如果不存在,继续去找onSeekTargetStep(dx, dy, recyclerView.mState, mRecyclingAction);
boolean hadJumpTarget = mRecyclingAction.hasJumpTarget();
mRecyclingAction.runIfNecessary(recyclerView);
if (hadJumpTarget) {
// It is not stopped so needs to be restarted
if (mRunning) {
mPendingInitialRun = true;
recyclerView.mViewFlinger.postOnAnimation();
} else {
stop(); // done复制代码
public void run() {
...省略部分代码
if (scroller.computeScrollOffset()) {
final int[]scrollConsumed = mScrollConsumed;
final int x = scroller.getCurrX();
final int y = scroller.getCurrY();
int dx = x - mLastFlingX;
int dy = y - mLastFlingY;
int hresult = 0;
int vresult = 0;mLastFlingX = x;mLastFlingY = y;
int overscrollX = 0, overscrollY = 0;
...省略部分代码
if (mAdapter != null) {
startInterceptRequestLayout();
onEnterLayoutOrScroll();
TraceCompat.beginSection(TRACE_SCROLL_TAG);
fillRemainingScrollValues(mState);
if (dx != 0) {//如果横向方向大于0,开始让RecyclerView滚动
hresult = mLayout.scrollHorizontallyBy(dx, mRecycler, mState);overscrollX = dx - hresult;
if (dy != 0) {//如果竖直方向大于0,开始让RecyclerView滚动,获得当前滚动的距离
vresult = mLayout.scrollVerticallyBy(dy, mRecycler, mState);overscrollY = dy - vresult;
TraceCompat.endSection();
repositionShadowingViews();
onExitLayoutOrScroll();
stopInterceptRequestLayout(false);
if (smoothScroller != null && !smoothScroller.isPendingInitialRun()
&& smoothScroller.isRunning()) {
final int adapterSize = mState.getItemCount();
if (adapterSize == 0) {
smoothScroller.stop();
} else if (smoothScroller.getTargetPosition() >= adapterSize) {
smoothScroller.setTargetPosition(adapterSize - 1);
//传入当前RecylerView滚动的距离 dx dy
smoothScroller.onAnimation(dx - overscrollX, dy - overscrollY);
} else {
//传入当前RecylerView滚动的距离 dx dy
smoothScroller.onAnimation(dx - overscrollX, dy - overscrollY);
enableRunOnAnimationRequests();复制代码
这里scroller(拿到之前Action传入的滑动距离信息)已经开始滑动了,故 if (scroller.computeScrollOffset()) 条件为true, 那么scroller拿到当前竖直方向的值就开始让RecyclerView滚动了,也就是代码 mLayout.scrollVerticallyBy(dy, mRecycler, mState);接着又让smoothScroller执行onAnimation()方法。其中传入的参数是RecyclerView已经滚动的距离。那我们现在继续看onAnimation方法。
private void onAnimation(int dx, int dy) {
final RecyclerView recyclerView = mRecyclerView;
if (!mRunning || mTargetPosition == RecyclerView.NO_POSITION || recyclerView == null) {
stop();
mPendingInitialRun = false;
if (mTargetView != null) {
// verify target position
if (getChildPosition(mTargetView) == mTargetPosition) {
onTargetFound(mTargetView, recyclerView.mState, mRecyclingAction);
mRecyclingAction.runIfNecessary(recyclerView);
stop();
} else {
Log.e(TAG, "Passed over target position while smooth scrolling.");
mTargetView = null;
if (mRunning) {//获得当前Recycler需要滚动的距离onSeekTargetStep(dx, dy, recyclerView.mState, mRecyclingAction);
boolean hadJumpTarget = mRecyclingAction.hasJumpTarget();
mRecyclingAction.runIfNecessary(recyclerView);
if (hadJumpTarget) {
// It is not stopped so needs to be restarted
if (mRunning) {
mPendingInitialRun = true;
recyclerView.mViewFlinger.postOnAnimation();
} else {
stop(); // done复制代码
publicintcalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int
snapPreference) {
switch (snapPreference) {
case SNAP_TO_START:
return boxStart - viewStart;
case SNAP_TO_END:
return boxEnd - viewEnd;
case SNAP_TO_ANY:
finalintdtStart= boxStart - viewStart;
if (dtStart > 0) {//滚动位置在可见范围之前return dtStart;
finalintdtEnd= boxEnd - viewEnd;
if (dtEnd < 0) {//滚动位置在可见范围之后return dtEnd;
break;
default:
thrownewIllegalArgumentException("snap preference should be one of the"
+ " constants defined in SmoothScroller, starting with SNAP_");
return0;//在可见范围之内,直接返回复制代码