下面是分析ListView初始化的源码流程分析,主要是ListVIew.onLayout过程与普通视图的layout过程完全不同,避免流程交代不清楚,以下是一个流程的思维导图。
思维导图是顺序是从左向右,从上向下。
一、 先看构造函数,上图中1.1就不分析了,主要是读取一些ListView参数,直接来看1.2 ViewGroup构造函数源码
private void initViewGroup() {
......
// 初始化保存当前ViewGroup中所有View的数组
mChildren = new View[ARRAY_INITIAL_CAPACITY];
// 初始时其Child个数为0
mChildrenCount = 0;
......
}
视图的创建过程的都会执行的三个步骤: onMeasure, onLayout, onDraw
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Sets up mListPadding
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获取当前ListView总宽高
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
......
setMeasuredDimension(widthSize , heightSize);
mWidthMeasureSpec = widthMeasureSpec;
}
三、步骤3是重点,AbsListView.onLayout的流程与普通View的不同
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mInLayout = true;
// 初始时changed = true
if (changed) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
// ?
getChildAt(i).forceLayout();
}
mRecycler.markChildrenDirty();
}
if (mFastScroller != null && mItemCount != mOldItemCount) {
mFastScroller.onItemCountChanged(mOldItemCount, mItemCount);
}
// ListView实现此方法
layoutChildren();
mInLayout = false;
mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR;
}
四、步骤4.1 具体分析ListVIew.layoutChildren
@Override
protected void layoutChildren() {
// 默认为false
final boolean blockLayoutRequests = mBlockLayoutRequests;
if (!bl