ChildHelper类
这个类中有两类方法:
- 第一类方法是许多和ViewGroup方法中重名的方法,例如getChildAt、getChildCount等等,这些方法内部实现是不包括mHiddenViews的,举个例子,例如getChildCount方法:
return mCallback.getChildCount() - mHiddenViews.size();
;如果想直接访问ViewGroup中的方法,可以调用***Unfiltered***
类的方法,例如getUnfilteredChildCount:return mCallback.getChildCount();
- 第二类方法是除去第一类方法的所有和mHiddenViews相关的方法
在RecyclerView中mCallback的实现类是在初始化ChildHelper中传入了一个内部匿名类:
new ChildHelper.Callback() {
@Override
public int getChildCount() {
return RecyclerView.this.getChildCount();
}
....
}
从实现类来看,ChildHelper的Callback接口的实现方法无非是调用RecyclerView的同名方法而已
ViewHolder中的标记
标记 | 说明 | 应用 |
---|---|---|
FLAG_BOUND = 1 << 0 | 这个ViewHolder已经和一个位置绑定,mItemId 和 mItemViewType都是有效的 | |
FLAG_UPDATE = 1 << 1 | 这个ViewHolder的视图对应的数据不是最新的,需要更新,mPosition 和 mItemId是一致的 | |
FLAG_INVALID = 1 << 2 | 这个ViewHolder的数据是无效的,mPosition 和 mItemId 可能不再与itemview的类型相匹配 | |
FLAG_REMOVED = 1 << 3 | 这个ViewHolder指向的数据已经从item的数据集中删除了,但是它的视图仍然可以用于outgoing动画等 | |
FLAG_NOT_RECYCLABLE = 1 << 4 | 这个ViewHolder不应该被回收。 这个标志是通过setIsRecyclable()设置,用于在动画期间保持子View不变。 | |
FLAG_IGNORE = 1 << 7 | 这个ViewHolder完全由LayoutManager管理。 我们不会将它加入缓存、回收或移除,除非LayoutManager被替换 | |
FLAG_MOVED = 1 << 11 | 当ViewHolder的position发生变化时,由ItemAnimator使用 |
将ChildHelper中的子View放入缓存中 —— detachAndScrapAttachedViews
例如之前在fill中填充布局的顺序是按照0->1->2->3->4的顺序来添加到RecyclerView中的话,那么现在加入到缓存的顺序恰恰相反是按照4->3->2->1->0的顺序
- 满足以下条件则添加到mCachedViews缓存中,且remove对应的View
if (viewHolder.isInvalid() && !viewHolder.isRemoved() &&
!mRecyclerView.mAdapter.hasStableIds())
- 满足以下添加则添加到mAttachedScrap缓存中,且detach对应的View
if (holder.hasAnyOfTheFlags(ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_INVALID)
|| !holder.isUpdated() || canReuseUpdatedViewHolder(holder)) {
- 否则添加到mChangedScrap缓存中,且detach对应的View