RecyclerView#smoothScrollToPosition调用RecyclerView.OnScrollListener的过程

项目中使用到了RecyclerView#smoothScrollToPosition(0)方法让Recyclerview滚动到顶部,同时给Recyclerview设置了监听器RecyclerView.OnScrollListener,代码如下所示:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
recyclerView.smoothScrollToPosition(0);

这里想简单聊下代码调用的过程。

RecyclerView#addOnScrollListener():
实现如下:
public void addOnScrollListener(OnScrollListener listener) {
    if (mScrollListeners == null) {
        mScrollListeners = new ArrayList<>();
    mScrollListeners.add(listener);
将监听器添加进RecyclerView的成员变量List<OnScrollListener> mScrollListeners中。

我们看下使用mScrollListeners的值的地方,有两处:

RecyclerView#dispatchOnScrolled
RecyclerView#dispatchOnScrollStateChanged

好,接下来我们看下recyclerView.smoothScrollToPosition()是如何调用到我们刚才添加的OnScrollListener监听器的:

RecyclerView#smoothScrollToPosition(int position) 
RecyclerView.LayoutManager#smoothScrollToPosition(RecyclerView recyclerView, State state, int position)
--> 实现类
LinearLayoutManager#smoothScrollToPosition(RecyclerView recyclerView, State state, int position)
LinearLayoutManager#startSmoothScroll(SmoothScroller smoothScroller)
mRecyclerView.mViewFlinger.postOnAnimation();
Recyclerview.SmoothScroller#start(RecyclerView recyclerView, LayoutManager layoutManager)
mRecyclerView.mViewFlinger.postOnAnimation();
RecyclerView.ViewFlinger#postOnAnimation()
ViewCompat.postOnAnimation(RecyclerView.this, this);
RecyclerView.ViewFlinger#run()
if (hresult != 0 || vresult != 0) {
    dispatchOnScrolled(hresult, vresult);

好了,这里调用到了我们刚才记录下来的RecyclerView#dispatchOnScrolled了,这个方法里面我们会依次调用RecyclerView的mScrollListeners。

代码如下所示:

void dispatchOnScrolled(int hresult, int vresult) {
    if (mScrollListeners != null) {
        for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
            mScrollListeners.get(i).onScrolled(this, hresult, vresult);
    mDispatchScrollCounter--;
				
1.recyclerView中,scrollToPosition 不会触发 scrollListener,而 smoothScrollToPosition 会触发 scrollListener 。源码分析可参考 2.监听 smoothScrollToPosition 滑动动画停止时,的例子: private void scrollToPosition(int position){ recyclerView.removeOnScrollListener(onScrollListener); RecyclerView 滑动 到指定的Item 有两个 常用的方法 ScrollToPosition(int position)smoothScrollToPosition(int position) * Starts a smooth scroll to an adapter position. * &amp;lt;p&amp;gt; * To support sm...
一、OnScrollListener的两个方法被执行时机 //用来标记是否正在向最后一个滑动 boolean isSlidingToLast = false; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newSt
Recyclerview滑动对齐方式 遇到一个问题,就是常见的双击让Recyclerview跳到知道position,但是跳转却是到对应position的底部,而不是上面对齐。 方法:smoothScrollToPosition(position) Recyclerview空实现smoothScrollToPosition,最后由对应的LayoutManager实现,这里是LinearLayoutManager @Override public void smoothScrollToPosi
本以为RecyclerView会像ListView一样有smoothScrollToPosition的方法,用来做双击返回列表顶部的方法,但实际添加这个方法以后并没有什么卵用,于是查看器源代码 public void smoothScrollToPosition(int position) { if (mLayoutFrozen) { return;
scrollToPositionWithOffset:offset - 项目视图的起始边缘与RecyclerView的起始边缘之间的距离(以像素为单位)。这里相比scrollToPosition,我们就可以设置偏移量: 如果offset = 0,我们可以理解为将目标Item刻意的滚动到顶部第一个可见位置,如果offset = 100,将目标Item刻意的滚动到距离顶部第一个可见位置往下偏移100px,然后以此类推... 如果只是想使某个位置可见,请使用scrollToPosition(int)
关于recyclerview滑向指定位置,肯定会想到scrollToPosition和smoothScrollToPosition两个方法。 源码分析scrollToPosition,最后会调用view的requestLayout,requestLayout是一个非常霸道的方法,会把UI线程全部锁死直到自己完成才会再次解锁。所以这个方法经常调用会出现卡顿。 而smoothScroll...
前言:使用RecyclerView时,调用smoothScrollToPostion()方法滑动到指定位置,但是条目很多时滑动的很慢,本篇文章就旨在实现RecyclerView的快速滑动。先介绍如何实现,然后再介绍原理。1. 实现代码 创建FastScrollLinearLayoutManager,继承LinearLayoutManager 复写smoothScrollToPosition()方法,
最近在开发的时候,遇到了需要通过代码使得RecyclerView能够滑到指定item顶部位置的需求,在查看源码之后,发现RecyclerView已经提供了实现滑动到指定位置的方法,下面是可实现方法: //平滑滚动 recyclerView.smoothScrollToPosition(position); //非平滑滚动 recyclerView.scrollToPosition(position...