Recyclerview是现在项目里使用频率越来越多的一个支持列表、网格、瀑布流的一个控件。且支持动画,支持自定义布局管理器。功能强大且灵活。同时还封装了viewHolder。但是RecyclerView是一个ViewGroup对象,所以要注意三个方法,onMeasure onLayout onDraw。
通过简单使用流程,来分析每个过程都做了哪些工作。
// 创建对象
recyclerView = this.findViewById(R.id.rv_test);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this,datas);
recyclerView.setAdapter(adapter);
a.创建RecyclerView对象,查看初始化对象都做了哪些工作
b.设置布局管理器,布局管理器做了什么。
c.创建适配器,适配器都有什么功能。
d.RecyclerView绑定适配器后,都有哪些逻辑,如果把数据展示出来。
RecyclewView对象大概有7000+代码,代码量大,只看重点。
public RecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// 创建一个观察者对象,支持监听item的移除,移动,插入,改变
this.mObserver = new RecyclerView.RecyclerViewDataObserver();
this.mRecycler = new RecyclerView.Recycler();
this.mViewInfoStore = new ViewInfoStore();
this.mUpdateChildViewsRunnable = new Runnable() {
public void run() {
if (RecyclerView.this.mFirstLayoutComplete && !RecyclerView.this.isLayoutRequested()) {
if (!RecyclerView.this.mIsAttached) {
RecyclerView.this.requestLayout();
} else if (RecyclerView.this.mLayoutFrozen) {
RecyclerView.this.mLayoutWasDefered = true;
} else {
RecyclerView.this.consumePendingUpdateOperations();
}
}
}
};
this.mTempRect = new Rect();
this.mTempRect2 = new Rect();
this.mTempRectF = new RectF();
this.mItemDecorations = new ArrayList();
this.mOnItemTouchListeners = new ArrayList();
this.mInterceptRequestLayoutDepth = 0;
this.mDataSetHasChangedAfterLayout = false;
this.mDispatchItemsChangedEvent = false;
this.mLayoutOrScrollCounter = 0;
this.mDispatchScrollCounter = 0;
this.mEdgeEffectFactory = new RecyclerView.EdgeEffectFactory();
this.mItemAnimator = new DefaultItemAnimator();
this.mScrollState = 0;
this.mScrollPointerId = -1;
this.mScaledHorizontalScrollFactor = 1.4E-45F;
this.mScaledVerticalScrollFactor = 1.4E-45F;
this.mPreserveFocusAfterLayout = true;
this.mViewFlinger = new RecyclerView.ViewFlinger();
this.mPrefetchRegistry = ALLOW_THREAD_GAP_WORK ? new LayoutPrefetchRegistryImpl() : null;
this.mState = new RecyclerView.State();
this.mItemsAddedOrRemoved = false;
this.mItemsChanged = false;
this.mItemAnimatorListener = new RecyclerView.ItemAnimatorRestoreListener();
this.mPostedAnimatorRunner = false;
this.mMinMaxLayoutPositions = new int[2];
this.mScrollOffset = new int[2];
this.mScrollConsumed = new int[2];
this.mNestedOffsets = new int[2];
this.mScrollStepConsumed = new int[2];
this.mPendingAccessibilityImportanceChange = new ArrayList();
this.mItemAnimatorRunner = new Runnable() {
public void run() {
if (RecyclerView.this.mItemAnimator != null) {
RecyclerView.this.mItemAnimator.runPendingAnimations();
}
RecyclerView.this.mPostedAnimatorRunner = false;
}
};
this.mViewInfoProcessCallback = new ProcessCallback() {
public void processDisappeared(RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo info, @Nullable RecyclerView.ItemAnimator.ItemHolderInfo postInfo) {
RecyclerView.this.mRecycler.unscrapView(viewHolder);
RecyclerView.this.animateDisappearance(viewHolder, info, postInfo);
}
public void processAppeared(RecyclerView.ViewHolder viewHolder, RecyclerView.ItemAnimator.ItemHolderInfo preInfo, RecyclerView.ItemAnimator.ItemHolderInfo info) {
RecyclerView.this.animateAppearance(viewHolder, preInfo, info);
}
public void processPersistent(RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo preInfo, @NonNull RecyclerView.ItemAnimator.ItemHolderInfo postInfo) {
viewHolder.setIsRecyclable(false);
if (RecyclerView.this.mDataSetHasChangedAfterLayout) {
if (RecyclerView.this.mItemAnimator.animateChange(viewHolder, viewHolder, preInfo, postInfo)) {
RecyclerView.this.postAnimationRunner();
}
} else if (RecyclerView.this.mItemAnimator.animatePersistence(viewHolder, preInfo, postInfo)) {
RecyclerView.this.postAnimationRunner();
}
}
public void unused(RecyclerView.ViewHolder viewHolder) {
RecyclerView.this.mLayout.removeAndRecycleView(viewHolder.itemView, RecyclerView.this.mRecycler);
}
};
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, CLIP_TO_PADDING_ATTR, defStyle, 0);
this.mClipToPadding = a.getBoolean(0, true);
a.recycle();
} else {
this.mClipToPadding = true;
}
this.setScrollContainer(true);
this.setFocusableInTouchMode(true);
ViewConfiguration vc = ViewConfiguration.get(context);
this.mTouchSlop = vc.getScaledTouchSlop();
this.mScaledHorizontalScrollFactor = ViewConfigurationCompat.getScaledHorizontalScrollFactor(vc, context);
this.mScaledVerticalScrollFactor = ViewConfigurationCompat.getScaledVerticalScrollFactor(vc, context);
this.mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
this.mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
this.setWillNotDraw(this.getOverScrollMode() == 2);
this.mItemAnimator.setListener(this.mItemAnimatorListener);
this.initAdapterManager();
this.initChildrenHelper();
this.initAutofill();
if (ViewCompat.getImportantForAccessibility(this) == 0) {
ViewCompat.setImportantForAccessibility(this, 1);
}
this.mAccessibilityManager = (AccessibilityManager)this.getContext().getSystemService("accessibility");
this.setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(this));
boolean nestedScrollingEnabled = true;
if (attrs != null) {
int defStyleRes = 0;
TypedArray a = context.obtainStyledAttributes(attrs, styleable.RecyclerView, defStyle, defStyleRes);
String layoutManagerName = a.getString(styleable.RecyclerView_layoutManager);
int descendantFocusability = a.getInt(styleable.RecyclerView_android_descendantFocusability, -1);
if (descendantFocusability == -1) {
this.setDescendantFocusability(262144);
}
this.mEnableFastScroller = a.getBoolean(styleable.RecyclerView_fastScrollEnabled, false);
if (this.mEnableFastScroller) {
StateListDrawable verticalThumbDrawable = (StateListDrawable)a.getDrawable(styleable.RecyclerView_fastScrollVerticalThumbDrawable);
Drawable verticalTrackDrawable = a.getDrawable(styleable.RecyclerView_fastScrollVerticalTrackDrawable);
StateListDrawable horizontalThumbDrawable = (StateListDrawable)a.getDrawable(styleable.RecyclerView_fastScrollHorizontalThumbDrawable);
Drawable horizontalTrackDrawable = a.getDrawable(styleable.RecyclerView_fastScrollHorizontalTrackDrawable);
this.initFastScroller(verticalThumbDrawable, verticalTrackDrawable, horizontalThumbDrawable, horizontalTrackDrawable);
}
a.recycle();
this.createLayoutManager(context, layoutManagerName, attrs, defStyle, defStyleRes);
if (VERSION.SDK_INT >= 21) {
a = context.obtainStyledAttributes(attrs, NESTED_SCROLLING_ATTRS, defStyle, defStyleRes);
nestedScrollingEnabled = a.getBoolean(0, true);
a.recycle();
}
} else {
this.setDescendantFocusability(262144);
}
this.setNestedScrollingEnabled(nestedScrollingEnabled);
}