RecyclerView刷新机制

本文详细分析了RecyclerView在`adapter.notifyDataSetChanged()`触发刷新时的内部逻辑,包括`RecyclerView.onLayout`方法中的`dispatchLayoutStep2()`,以及`LinearLayoutManager.onLayoutChildren()`中的布局过程,如确定锚点View、计算布局空间和摆放子View。此外,还探讨了在滑动时,RecyclerView如何通过`LinearLayoutManager.scrollBy`方法进行滚动更新,展示了从确定可用布局空间到滚动显示新布局的过程。
摘要由CSDN通过智能技术生成

前面分析了RecyclerView的基本结构
本文继续来看一下RecyclerView是如何完成UI的刷新以及在滑动时子View的添加逻辑

本文会从源码分析两件事 :

  1. adapter.notifyXXX()时RecyclerView的UI刷新的逻辑,即子View是如何添加到RecyclerView中的。
  2. 在数据存在的情况下,滑动RecyclerView子View是如何添加到RecyclerView并滑动的。

本文不会涉及到RecyclerView的动画,动画的实现会专门在一篇文章中分析。

adapter.notifyDataSetChanged()引起的刷新

我们假设RecyclerView在初始状态是没有数据的,然后往数据源中加入数据后,调用adapter.notifyDataSetChanged()来引起RecyclerView的刷新:

 

data.addAll(datas)
adapter.notifyDataSetChanged()

用图描述就是下面两个状态的转换:

 

adapter.notifyDataSetChanged.png

接下来就来分析这个变化的源码,在上一篇文章中已经解释过,adapter.notifyDataSetChanged()时,会引起RecyclerView重新布局(requestLayout),RecyclerViewonMeasure就不看了,核心逻辑不在这里。因此从onLayout()方法开始看:

RecyclerView.onLayout

这个方法直接调用了dispatchLayout:

 

void dispatchLayout() {
    ...
    if (mState.mLayoutStep == State.STEP_START) {
        dispatchLayoutStep1();
        dispatchLayoutStep2();
    } else if (数据变化 || 布局变化) {
        dispatchLayoutStep2();
    }
    dispatchLayoutStep3();
}

上面我裁剪掉了一些代码,可以看到整个布局过程总共分为3步, 下面是这3步对应的方法:

 

STEP_START ->  dispatchLayoutStep1()
STEP_LAYOUT -> dispatchLayoutStep2()
STEP_ANIMATIONS -> dispatchLayoutStep2(), dispatchLayoutStep3()

第一步STEP_START主要是来存储当前子View的状态并确定是否要执行动画。这一步就不细看了。 而第3步STEP_ANIMATIONS是来执行动画的,本文也不分析了,本文主要来看一下第二步STEP_LAYOUT,即dispatchLayoutStep2():

dispatchLayoutStep2()

先来看一下这个方法的大致执行逻辑:

 

private void dispatchLayoutStep2() {  
    startInterceptRequestLayout(); //方法执行期间不能重入
    ...
    //设置好初始状态
    mState.mItemCount = mAdapter.getItemCount();
    mState.mDeletedInvisibleItemCountSincePreviousLayout = 0;
    mState.mInPreLayout = false;

    mLayout.onLayoutChildren(mRecycler, mState); //调用布局管理器去布局

    mState.mStructureChanged = false;
    mPendingSavedState = null;
    ...
    mState.mLayoutStep = State.STEP_ANIMATIONS; //接下来执行布局的第三步

    stopInterceptRequestLayout(false);
}

这里有一个mState,它是一个RecyclerView.State对象。顾名思义它是用来保存RecyclerView状态的一个对象,主要是用在LayoutManager、Adap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值