RecyclerView 的使用:
RecyclerView lv = (RecyclerView) findViewById(R.id.lv);
lv.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
lv.setAdapter(new MyListAdapter(getApplicationContext()));
setLayoutManager 给 RecyclerView 设置了 mLayout, setAdapter 设置 mAdapter, 清除缓存的一些信息,并 requestLayout. RecyclerView 执行 onLayout 过程中,会调用 mLayout.layoutChildren 方法,然后到 LinearLayoutManager 的 layoutChildren 方法,fill(recycler, mLayoutState, state, false) 再到 layoutChunk 方法中看,第一行代码就是 layoutState.next(recycler), 进去看这个方法,这个方法获取了下一个需要 layout 的 view, 看下源码:
if (mScrapList != null) {
// mScrapList 不为 null, 则取 mScrapList 中的 View
return nextViewFromScrapList();
}
// mScrapList 为 null, 则继续查找 view, 从 getViewForPosition, tryGetViewHolderForPositionByDeadline 方法看
final View view = recycler.getViewForPosition(mCurrentPosition);
mCurrentPosition += mItemDirection;
return view;
tryGetViewHolderForPositionByDeadline 方法,主要查缓存 View 的地方
ViewHolder tryGetViewHolderForPositionByDeadline(int position,
boolean dryRun, long deadlineNs) {
boolean fromScrapOrHiddenOrCache = false;
ViewHolder holder = null;
// 0) 首先从 mChangeScrap 中查
if (mState.isPreLayout()) {
holder = getChangedScrapViewForPosition(position);
fromScrapOrHiddenOrCache = holder != null;
}
// 1) 没有找到就从 mAttachView 或 mCacheView 中查
if (holder == null) {
holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);
if (holder != null) {
// ...
}
}
if (holder == null) {
final int type = mAdapter.getItemViewType(offsetPosition);
// 2) 通过 stableIs 在 mAttachView 和 mCacheView 中查
if (mAdapter.hasStableIds()) {
holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),
type, dryRun);
if (holder != null) {
// ...
}
}
if (holder == null && mViewCacheExtension != null) {
// 通过 mViewCacheExtension 查
}
if (holder == null) { // 从 mRecyclerPool 中查
holder = getRecycledViewPool().getRecycledView(type);
if (holder != null) {
// ...
}
}
if (holder == null) {
// 自己创建 View, 也就是我们自己实现的 onCreateViewHolder 方法
holder = mAdapter.createViewHolder(RecyclerView.this, type);
// ...
}
}
// ...
// 设置 layoutParams
return holder;
}
layout 过程中就是以上面的方式获取缓存的 View, 然后加到 RecyclerView 中。
下面再看滑动过程中 item 是怎么复用的,RecyclerView 的 onTouchEvent 方法 ACTION_MOVE 事件中调用了 mGapWorker.postFromTraversal(this, dx, dy), 接着到 GapWorker 中看,它的 postFromTraversal 方法主要执行了 recycleview.post(this), GapWorker 是一个 Runnable, 那么执行的就是 GapWorker 的 run() 方法,在这里面一直跟进去 prefetch, flushTasksWithDeadline, prefetchPositionWithDeadline, 我们能看到在 prefetchPositionWithDeadline 方法中同样调了 recycler.tryGetViewHolderForPositionByDeadline 来获取缓存中的 ViewHolder, 所以滑动过程中 item 的复用就是这样实现的。
好吧,分析的不是很清晰,先到这里吧,继续看源码(^▽^)