- 先找入口,recycleview只有一个地方调用了addView,全局搜索:
RecyclerView.this.addView(child, index);
- 往上搜寻:
ChildHelper.addView()
LayoutManager.addViewInt()
LayoutManager.addView()
LinearLayoutManager.layoutChunk()
- 找到关键节点,往下搜寻,LinearLayoutManager.layoutChunk()中:
layoutState.next(recycler)
recycler.getViewForPosition(mCurrentPosition)
- 最终找到这个方法
ViewHolder tryGetViewHolderForPositionByDeadline(int position,boolean dryRun, long deadlineNs)
ViewHolder tryGetViewHolderForPositionByDeadline(int position,boolean dryRun, long deadlineNs) {
...
// 0) If there is a changed scrap, try to find from there
if (mState.isPreLayout()) {
/**
* 1.特殊情况:isPreLayout()预布局
* 从 changeScrap 获取
*/
holder = getChangedScrapViewForPosition(position);
...
}
// 1) Find by position from scrap/hidden list/cache
if (holder == null) {
/**
* 2.从废料、隐藏View、缓存中获取
* mAttachedScrap『ArrayList<VH>』
* mHiddenViews『ArrayList<View>』
* mCachedViews『ArrayList<VH>』
*/
holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);
...
}
if (holder == null) {
...
// 2) Find from scrap/cache via stable ids, if exists
if (mAdapter.hasStableIds()) {
/**
* 3.特殊情况:当adapter设置了id,和2一样,2是用的position
*/
holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition), type, dryRun);
...
}
if (holder == null && mViewCacheExtension != null) {
// We are NOT sending the offsetPosition because LayoutManager does not
// know it.
/**
* 4.特殊情况:用户自定义缓存
* ViewCacheExtension
*/
final View view = mViewCacheExtension.getViewForPositionAndType(this, position, type);
if (view != null) {
holder = getChildViewHolder(view);
...
}
}
if (holder == null) { // fallback to pool
...
/**
* 5.从回收池获取:RecycleViewPool『ArrayList<ViewHolder>』
*/
holder = getRecycledViewPool().getRecycledView(type);
...
}
if (holder == null) {
/**
* 6.不走回收,直接创建
*/
holder = mAdapter.createViewHolder(RecyclerView.this, type);
...
}
}
...
return holder;
}
细节内容分析推荐:juejin.cn/post/684490…