//存放废弃的viewfinalArrayList<ViewHolder>mAttachedScrap=newArrayList<>();//存放改变的废弃的viewArrayList<ViewHolder>mChangedScrap=null;//缓存viewfinalArrayList<ViewHolder>mCachedViews=newArrayList<ViewHolder>();//最多缓存个数intmViewCacheMax=DEFAULT_CACHE_SIZE;//默认缓存为2staticfinalintDEFAULT_CACHE_SIZE=2;//更新缓存大小voidupdateViewCacheSize(){intextraCache=mLayout!=null?mLayout.mPrefetchMaxCountObserved:0;mViewCacheMax=mRequestedCacheMax+extraCache;// first, try the views that can be recycledfor(inti=mCachedViews.size()-1;i>=0&&mCachedViews.size()>mViewCacheMax;i--){recycleCachedViewAt(i);}}
//从mCachedViews中移除voidrecycleCachedViewAt(intcachedViewIndex){ViewHolderviewHolder=mCachedViews.get(cachedViewIndex);//从mCachedViews中移除添加到RecycledViewPooladdViewHolderToRecycledViewPool(viewHolder,true);mCachedViews.remove(cachedViewIndex);}//添加到RecycledViewPoolvoidaddViewHolderToRecycledViewPool(@NonNullViewHolderholder,booleandispatchRecycled){clearNestedRecyclerViewIfNotNested(holder);ViewitemView=holder.itemView;//holder.mBindingAdapter=null;holder.mOwnerRecyclerView=null;//调用RecycledViewPool的putRecycledView方法getRecycledViewPool().putRecycledView(holder);}//添加到mCachedViews中voidrecycleViewHolderInternal(ViewHolderholder){if(forceRecycle||holder.isRecyclable()){//存入到mCachedViews中if(mViewCacheMax>0&&!holder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID|ViewHolder.FLAG_REMOVED|ViewHolder.FLAG_UPDATE|ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)){// Retire oldest cached viewintcachedViewSize=mCachedViews.size();//当mCachedViews size超过最大缓存数时移除第一个if(cachedViewSize>=mViewCacheMax&&cachedViewSize>0){recycleCachedViewAt(0);cachedViewSize--;}inttargetCacheIndex=cachedViewSize;if(ALLOW_THREAD_GAP_WORK&&cachedViewSize>0&&!mPrefetchRegistry.lastPrefetchIncludedPosition(holder.mPosition)){// when adding the view, skip past most recently prefetched viewsintcacheIndex=cachedViewSize-1;while(cacheIndex>=0){intcachedPos=mCachedViews.get(cacheIndex).mPosition;if(!mPrefetchRegistry.lastPrefetchIncludedPosition(cachedPos)){break;}cacheIndex--;}targetCacheIndex=cacheIndex+1;}mCachedViews.add(targetCacheIndex,holder);cached=true;}//不满足条件的时候存入RecyclerViewPoolif(!cached){addViewHolderToRecycledViewPool(holder,true);recycled=true;}}else{// NOTE: A view can fail to be recycled when it is scrolled off while an animation// runs. In this case, the item is eventually recycled by// ItemAnimatorRestoreListener#onAnimationFinished.// TODO: consider cancelling an animation when an item is removed scrollBy,// to return it to the pool faster}}//voidrecycleAndClearCachedViews(){finalintcount=mCachedViews.size();for(inti=count-1;i>=0;i--){recycleCachedViewAt(i);}mCachedViews.clear();//...}
/** * Mark an attached view as scrap. * * <p>"Scrap" views are still attached to their parent RecyclerView but are eligible * for rebinding and reuse. Requests for a view for a given position may return a * reused or rebound scrap view instance.</p> * * @param view View to scrap */voidscrapView(Viewview){finalViewHolderholder=getChildViewHolderInt(view);if(holder.hasAnyOfTheFlags(ViewHolder.FLAG_REMOVED|ViewHolder.FLAG_INVALID)||!holder.isUpdated()||canReuseUpdatedViewHolder(holder)){if(holder.isInvalid()&&!holder.isRemoved()&&!mAdapter.hasStableIds()){thrownewIllegalArgumentException("Called scrap view with an invalid view."+" Invalid views cannot be reused from scrap, they should rebound from"+" recycler pool."+exceptionLabel());}holder.setScrapContainer(this,false);//添加到mAttachedScrap集合中mAttachedScrap.add(holder);}else{if(mChangedScrap==null){mChangedScrap=newArrayList<ViewHolder>();}holder.setScrapContainer(this,true);mChangedScrap.add(holder);}}voidclearScrap(){mAttachedScrap.clear();if(mChangedScrap!=null){mChangedScrap.clear();}}/** * Remove a previously scrapped view from the pool of eligible scrap. * * <p>This view will no longer be eligible for reuse until re-scrapped or * until it is explicitly removed and recycled.</p> */voidunscrapView(ViewHolderholder){if(holder.mInChangeScrap){mChangedScrap.remove(holder);}else{mAttachedScrap.remove(holder);}holder.mScrapContainer=null;holder.mInChangeScrap=false;holder.clearReturnedFromScrapFlag();}
//缓存池SparseArray<ScrapData>mScrap=newSparseArray<>();staticclassScrapData{finalArrayList<ViewHolder>mScrapHeap=newArrayList<>();intmMaxScrap=DEFAULT_MAX_SCRAP;longmCreateRunningAverageNs=0;longmBindRunningAverageNs=0;}//存入缓存publicvoidputRecycledView(ViewHolderscrap){finalintviewType=scrap.getItemViewType();finalArrayList<ViewHolder>scrapHeap=getScrapDataForType(viewType).mScrapHeap;if(mScrap.get(viewType).mMaxScrap<=scrapHeap.size()){return;}if(DEBUG&&scrapHeap.contains(scrap)){thrownewIllegalArgumentException("this scrap item already exists");}scrap.resetInternal();scrapHeap.add(scrap);}//从缓存中获取ViewHolder/** * Acquire a ViewHolder of the specified type from the pool, or {@code null} if none are * present. * * @param viewType ViewHolder type. * @return ViewHolder of the specified type acquired from the pool, or {@code null} if none * are present. */@NullablepublicViewHoldergetRecycledView(intviewType){finalScrapDatascrapData=mScrap.get(viewType);if(scrapData!=null&&!scrapData.mScrapHeap.isEmpty()){finalArrayList<ViewHolder>scrapHeap=scrapData.mScrapHeap;for(inti=scrapHeap.size()-1;i>=0;i--){if(!scrapHeap.get(i).isAttachedToTransitionOverlay()){returnscrapHeap.remove(i);}}}returnnull;}