code: protected void updateActionForInterimTarget(Action action) {
          // find an interim target position
          PointF scrollVector = computeScrollVectorForPosition(getTargetPosition());
          if (scrollVector == null || (scrollVector.x == 0 && scrollVector.y == 0)) {
              Log.e(TAG, "To support smooth scrolling, you should override \n"
                      + "LayoutManager#computeScrollVectorForPosition.\n"
                      + "Falling back to instant scroll");
              final int target = getTargetPosition();
              stop();
              instantScrollToPosition(target);
              return;
          }
          normalize(scrollVector);
          mTargetVector = scrollVector;
  
          mInterimTargetDx = (int) (TARGET_SEEK_SCROLL_DISTANCE_PX * scrollVector.x);
          mInterimTargetDy = (int) (TARGET_SEEK_SCROLL_DISTANCE_PX * scrollVector.y);
          final int time = calculateTimeForScrolling(TARGET_SEEK_SCROLL_DISTANCE_PX);
          // To avoid UI hiccups, trigger a smooth scroll to a distance little further than the
          // interim target. Since we track the distance travelled in onSeekTargetStep callback, it
          // won't actually scroll more than what we need.
          action.update((int) (mInterimTargetDx * TARGET_SEEK_EXTRA_SCROLL_RATIO)
                  , (int) (mInterimTargetDy * TARGET_SEEK_EXTRA_SCROLL_RATIO)
                  , (int) (time * TARGET_SEEK_EXTRA_SCROLL_RATIO), mLinearInterpolator);
      }
docs: When the target scroll position is not a child of the RecyclerView, this method calculates
  a direction vector towards that child and triggers a smooth scroll.
  
  @see #computeScrollVectorForPosition(int)