1.在 onCreateViewHolder 里面写点击事件
这个很好理解,onBindViewHolder会多次调用
2.LinearLayoutManager.setInitialPrefetchItemCount
注意,此方法LinearLayoutManager专属
public void setInitialPrefetchItemCount(int itemCount) {
mInitialItemPrefetchCount = itemCount;
}
mInitialItemPrefetchCount 在这里用到
@Override
public void collectInitialPrefetchPositions(int adapterItemCount,
LayoutPrefetchRegistry layoutPrefetchRegistry) {
final int direction = fromEnd
? LayoutState.ITEM_DIRECTION_HEAD
: LayoutState.ITEM_DIRECTION_TAIL;
int targetPos = anchorPos;
for (int i = 0; i < mInitialItemPrefetchCount; i++) {
if (targetPos >= 0 && targetPos < adapterItemCount) {
layoutPrefetchRegistry.addPosition(targetPos, 0);
} else {
break; // no more to prefetch
}
targetPos += direction;
}
}
说白了就是预取操作。collectInitialPrefetchPositions定义当此LayoutManager的RecyclerView嵌套在另一个RecyclerView中时应预取多少内部项目。也就是说只有RecyclerView嵌套才会生效,否则无效
3.setHasFixedSize
setHasFixedSize 会给 mHasFixedSize 赋值,看一下用到的地方
// 第一处
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
if (mLayout == null) {
defaultOnMeasure(widthSpec, heightSpec);
return;
}
if (mLayout.mAutoMeasure) {
......
} else {
if (mHasFixedSize) {
mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
return;
}
// custom onMeasure
if (mAdapterUpdateDuringMeasure) {
eatRequestLayout();
onEnterLayoutOrScroll();
processAdapterUpdatesAndSetAnimationFlags();
onExitLayoutOrScroll();
if (mState.mRunPredictiveAnimations) {
mState.mInPreLayout = true;
} else {
// consume remaining updates to provide a consistent state with the layout pass.
mAdapterHelper.consumeUpdatesInOnePass();
mState.mInPreLayout = false;
}
mAdapterUpdateDuringMeasure = false;
resumeRequestLayout(false);
}
if (mAdapter != null) {
mState.mItemCount = mAdapter.getItemCount();
} else {
mState.mItemCount = 0;
}
eatRequestLayout();
mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
resumeRequestLayout(false);
mState.mInPreLayout = false; // clear
}
}
// 第二处
private class RecyclerViewDataObserver extends AdapterDataObserver {
void triggerUpdateProcessor() {
if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
RecyclerView.this.postOnAnimation(mUpdateChildViewsRunnable);
} else {
mAdapterUpdateDuringMeasure = true;
requestLayout();
}
}
}
mLayout.mAutoMeasure 默认是false,当然也可以自己设置。当mHasFixedSize是true的时候只会执行onMeasure。另外,每次notifyDataSetChanged的时候只会mUpdateChildViews而不用整个requestLayout。当然,有个前提,adapter的数据变化不会导致RecycleView的大小变化 。
总结,当RecycleView大小固定的时候,setHasFixedSize 为true可以使每次onMeasure和notifyDataSet的时候不用去request整个layout
4.多个RecycleView共用RecycledViewPool
RecycledViewPool 其实并不陌生,就是缓存机制的最后一个pool。如果这里还取不到view就重新create。具体我也写过,参考 RecyclerView的缓存机制和内存优化