…
mState.mIsMeasuring = false;
if (mState.mLayoutStep == State.STEP_START) {
dispatchLayoutStep1();
mLayout.setExactMeasureSpecsFrom(this);
//测量子 View
dispatchLayoutStep2();
} else if (mAdapterHelper.hasUpdates() || mLayout.getWidth() != getWidth()
|| mLayout.getHeight() != getHeight()) {
mLayout.setExactMeasureSpecsFrom(this);
//测量子 View
dispatchLayoutStep2();
} else {
mLayout.setExactMeasureSpecsFrom(this);
}
//触发动画效果
dispatchLayoutStep3();
}
如果在 onMeasure 阶段没有执行 dispatchLayoutStep2() 方法去测量子 View,则会在 onLayout 阶段重新执行。
dispatchLayoutStep2
//在此步骤中,我们对最终状态的视图进行实际布局。
//如有必要,可多次运行此步骤(例如,measure)。
private void dispatchLayoutStep2() {
…
// Step 2: Run layout
mState.mInPreLayout = false;
mLayout.onLayoutChildren(mRecycler, mState);
…
}
public void onLayoutChildren(Recycler recycler, State state) {
Log.e(TAG, "You must override onLayoutChildren(Recycler recycler, State state) ");
}
核心逻辑是调用了 mLayout 的 onLayoutChildren 方法。
这个方法在 RecyclerView.LayoutManager 中的一个空方法,主要作用是测量 RecyclerView 内的子 View 大小,并确定它们所在的位置。
LinearLayoutManager、GridLayoutManager,以及 StaggeredLayoutManager 都分别复写了这个方法,并实现了不同方式的布局。
LinearLayoutManager.onLayoutChildren
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
…
//调用 fill 方法,完成子 View 的测量布局工作;
fill(recycler, mLayoutState, state, false);
…
}
//重点
int fill(RecyclerView.Recycler recycler, Layo