96SEO 2026-02-20 09:05 15
我们创建一个RecyclerView的Adapter#xff1a;

RecyclerView.AdapterMyRecyclerVie…概述
RecyclerView.AdapterMyRecyclerView.MyHolder
LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1,
MyHolder(view);Log.d(MyRecyclerView,
itemView.findViewById(android.R.id.text1);}}
我们在onCreateViewHolder和onBindViewHolder都打印log。
onCreateViewHolder()会在创建一个新view的时候调用onBindViewHolder()会在已存在view绑定数据的时候调用。
在最开始加载view的时候两个方法onCreateViewHolder()和onBindViewHolder()都执行了但是当我们上下滑动RecyclerView的时候我们会发现只执行了onBindViewHolder()方法。
所以说RecyclerView并不是会一直重新创建View而是会对view进行复用。
当我们想去通过看源码去了解缓存复用机制的时候我们要去想看源码的入口在哪里。
上文我们提到是在滑动RecyclerView的时候进行了缓存复用所以我们会想到去看
e.findPointerIndex(mScrollPointerId);if
{setScrollState(SCROLL_STATE_DRAGGING);}}if
(dispatchNestedPreScroll(canScrollHorizontally
mScrollOffset[0];mNestedOffsets[1]
interceptinggetParent().requestDisallowInterceptTouchEvent(true);}mLastTouchX
(scrollByInternal(canScrollHorizontally
{getParent().requestDisallowInterceptTouchEvent(true);}if
{mGapWorker.postFromTraversal(this,
}在case:MotionEvent.ACTION_MOVE里有
0;consumePendingUpdateOperations();if
mReusableIntPair[1];unconsumedX
{invalidate();}mReusableIntPair[0]
0;dispatchNestedScroll(consumedX,
mReusableIntPair[0];unconsumedY
mScrollOffset[1];mNestedOffsets[0]
mScrollOffset[0];mNestedOffsets[1]
!MotionEventCompat.isFromSource(ev,
unconsumedY);}considerReleasingGlowsOnScroll(x,
{startInterceptRequestLayout();onEnterLayoutOrScroll();TraceCompat.beginSection(TRACE_SCROLL_TAG);fillRemainingScrollValues(mState);int
mLayout.scrollHorizontallyBy(dx,
mState);}TraceCompat.endSection();repositionShadowingViews();onExitLayoutOrScroll();stopInterceptRequestLayout(false);if
0;}ensureLayoutState();mLayoutState.mRecycle
LinearLayoutManager.LayoutState.LAYOUT_END
LinearLayoutManager.LayoutState.LAYOUT_START;final
Math.abs(delta);updateLayoutState(layoutDirection,
delta;mOrientationHelper.offsetChildren(-scrolled);if
scrolled);}mLayoutState.mLastScrollDelta
LinearLayoutManager.LayoutState
{layoutChunkResult.resetInternal();if
LayoutChunk);}layoutChunk(recycler,
layoutState.mLayoutDirection;/***
(!layoutChunkResult.mIgnoreConsumed
layoutChunkResult.mConsumed;}if
LinearLayoutManager.LayoutState.SCROLLING_OFFSET_NaN)
layoutState.mAvailable;}recycleByLayoutState(recycler,
}这个方法功能是填充给定的布局通过while循环不断进行填充其中的
layoutChunk(RecyclerView.Recycler
layoutState.next(recycler);//获取下一项需要布局的视图if
true;return;}RecyclerView.LayoutParams
tryGetViewHolderForPositionByDeadline(int
IndexOutOfBoundsException(Invalid
getChangedScrapViewForPosition(position);fromScrapOrHiddenOrCache
getScrapOrHiddenOrCachedHolderForPosition(position,
(!validateViewHolderForOffsetPosition(holder))
etc.holder.addFlags(ViewHolder.FLAG_INVALID);if
{removeDetachedView(holder.itemView,
(holder.wasReturnedFromScrap())
{holder.clearReturnedFromScrapFlag();}recycleViewHolderInternal(holder);}holder
mAdapterHelper.findPositionOffset(position);if
IndexOutOfBoundsException(Inconsistency
mAdapter.getItemViewType(offsetPosition);//
getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),type,
offsetPosition;fromScrapOrHiddenOrCache
mViewCacheExtension.getViewForPositionAndType(this,
IllegalArgumentException(getViewForPositionAndType
IllegalArgumentException(getViewForPositionAndType
tryGetViewHolderForPositionByDeadline(
getRecycledViewPool().getRecycledView(type);if
(FORCE_INVALIDATE_DISPLAY_LIST)
{invalidateDisplayListInt(holder);}}}if
!mRecyclerPool.willCreateInTime(type,
mAdapter.createViewHolder(RecyclerView.this,
findNestedRecyclerView(holder.itemView);if
WeakReference(innerView);}}long
getNanoTime();mRecyclerPool.factorInCreateTime(type,
tryGetViewHolderForPositionByDeadline
holder.hasAnyOfTheFlags(ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST))
ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST);if
ItemAnimator.buildAdapterChangeFlagsForAnimations(holder);changeFlags
ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT;final
mItemAnimator.recordPreLayoutInformation(mState,holder,
holder.getUnmodifiedPayloads());recordAnimationInfoIfBouncedHiddenView(holder,
mAdapterHelper.findPositionOffset(position);bound
tryBindViewHolderByDeadline(holder,
holder.itemView.getLayoutParams();final
generateDefaultLayoutParams();holder.itemView.setLayoutParams(rvLayoutParams);}
generateLayoutParams(lp);holder.itemView.setLayoutParams(rvLayoutParams);}
holder;rvLayoutParams.mPendingInvalidate
getChangedScrapViewForPosition(position);fromScrapOrHiddenOrCache
true会优先从变更缓存中获取。
getChangedScrapViewForPosition(position)查找变更缓存mChangedScrap这里保存的是那些被标记为需要更新的ViewHolder。
如果找到直接返回不需要从其他层中查找。
为支持动画效果如插入、删除、移动等操作而执行的一个特殊布局阶段。
setHasStableIds布局管理器或动画的变化setLayoutManager,
setItemAnimator视图的移动notifyItemMoved所有与动画相关的操作包括添加、删除、移动动画
getScrapOrHiddenOrCachedHolderForPosition(position,
(!validateViewHolderForOffsetPosition(holder))
{holder.addFlags(ViewHolder.FLAG_INVALID);if
{removeDetachedView(holder.itemView,
(holder.wasReturnedFromScrap())
{holder.clearReturnedFromScrapFlag();}recycleViewHolderInternal(holder);}holder
Scrap表示那些视图项暂时不可见但还可以复用的视图它们是最常见的一种缓存方式。
被标记为废弃的视图在没有被回收之前可以复用。
Hidden隐藏视图与
类似但它们的存在通常是为了支持更复杂的布局切换、动画等。
它们在显示区域外但仍然保留在缓存中直到需要重新显示。
CacheRecyclerView
或类型等条件频繁访问的视图。
它们通常在视图池中存储较长时间直到达到缓存容量限制。
validateViewHolderForOffsetPosition(holder)检查缓存的有效性
如果无效比如位置错位将其回收。
如果有效标记fromScrapOrHiddenOrCache
getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),
offsetPosition;fromScrapOrHiddenOrCache
true尝试通过稳定ID查找缓存中的ViewHolder。
调用getScrapOrCachedViewForId通过ID获取匹配的ViewHolder。
如果找到将其位置更新为offsetPosition并标记为来自缓存。
RecyclerView.AdapterMyViewHolder
myDataList.get(position).getId();}//
MyRecyclerViewAdapter(ListString
getRecycledViewPool().getRecycledView(type);if
内部维护的一个缓存池用于存储已经被回收并不再使用的视图View。
这些视图通常是已经滑出屏幕或者暂时不可见的视图。
通过回收池RecyclerView
可以避免每次滚动时都重新创建视图而是将已回收的视图重新利用从而提升滚动性能。
会在视图不再需要时将它们放入回收池即已回收的视图池。
当需要新的视图时RecyclerView
回收池存储的是所有超出缓存数量限制的ViewHolder按type分类。
mAdapter.createViewHolder(RecyclerView.this,
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback