天天看點

android recyclerview局部重新整理,Android RecyclerView 局部重新整理分析

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

dispatchLayout();

mFirstLayoutComplete = true;

}

//2.mInPreLayout 設定為 true 後面有用

mState.mInPreLayout = mState.mRunPredictiveAnimations;

//5.儲存動畫資訊相關

mViewInfoStore.addToPreLayout(holder, animationInfo);

//3.如果holder确定要更新,就把它添加到 oldChangeHolders 集合中

long key = getChangedHolderKey(holder);

mViewInfoStore.addToOldChangeHolders(key, holder);

@VisibleForTesting

final LongSparseArray mOldChangedHolders = new LongSparseArray<>();

public void onLayoutChildren(Recycler recycler, State state) {

Log.e(TAG, "You must override onLayoutChildren(Recycler recycler, State state) ");

}

private void processAdapterUpdatesAndSetAnimationFlags() {

// 通常情況就是 ture

mState.mRunSimpleAnimations = true

// 通常情況就是 ture

mState.mRunPredictiveAnimations = true

mAdapterHelper.preProcess();

for (int i = 0; i < count; i++) {

UpdateOp op = mPendingUpdates.get(i);

case UpdateOp.UPDATE:

applyUpdate(op);

break;

UpdateOp newOp = obtainUpdateOp(UpdateOp.UPDATE, tmpStart, tmpCount,

op.payload);

postponeAndUpdateViewHolders(newOp);

case UpdateOp.UPDATE:

mCallback.markViewHoldersUpdated(op.positionStart, op.itemCount, op.payload);

break;

void initAdapterManager() {

mAdapterHelper = new AdapterHelper(new AdapterHelper.Callback() {

@Override

public void markViewHoldersUpdated(int positionStart, int itemCount, Object payload) {

viewRangeUpdate(positionStart, itemCount, payload);

mItemsChanged = true;

}

void viewRangeUpdate(int positionStart, int itemCount, Object payload) {

final int childCount = mChildHelper.getUnfilteredChildCount();

final int positionEnd = positionStart + itemCount;

if (holder.mPosition >= positionStart && holder.mPosition < positionEnd) {

// We re-bind these view holders after pre-processing is complete so that

// ViewHolders have their final positions assigned.

holder.addFlags(ViewHolder.FLAG_UPDATE);

holder.addChangePayload(payload);

// lp cannot be null since we get ViewHolder from it.

((LayoutParams) child.getLayoutParams()).mInsetsDirty = true;

}

processAdapterUpdatesAndSetAnimationFlags();

if (mState.mTrackOldChangeHolders && holder.isUpdated() && !holder.isRemoved()

&& !holder.shouldIgnore() && !holder.isInvalid()) {

long key = getChangedHolderKey(holder);

// This is NOT the only place where a ViewHolder is added to old change holders

// list. There is another case where:

//    * A VH is currently hidden but not deleted

//    * The hidden item is changed in the adapter

//    * Layout manager decides to layout the item in the pre-Layout pass (step1)

// When this case is detected, RV will un-hide that view and add to the old

// change holders list.

mViewInfoStore.addToOldChangeHolders(key, holder);

}

@VisibleForTesting

final LongSparseArray mOldChangedHolders = new LongSparseArray<>();

//4.很重要,LayoutManager 開始工作

mLayout.onLayoutChildren(mRecycler, mState);

for (int i = childCount - 1; i >= 0; i--) {

final View v = getChildAt(i);

scrapOrRecycleView(recycler, i, v);

}

return ((LayoutParams) child.getLayoutParams()).mViewHolder;

recycler.scrapView(view);

不更新

mAttachedScrap.add(holder);

public final class Recycler {

final ArrayList mAttachedScrap = new ArrayList<>();

更新的話

mChangedScrap.add(holder);

ArrayList mChangedScrap = null;

ViewHolder tryGetViewHolderForPositionByDeadline(int position,

boolean dryRun, long deadlineNs) {

if (mState.isPreLayout()) {

holder = getChangedScrapViewForPosition(position);

final ViewHolder holder = mChangedScrap.get(i);

holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);

final ViewHolder holder = mAttachedScrap.get(i);

Recycler

final ViewHolder holder = mCachedViews.get(i);

final ArrayList mCachedViews = new ArrayList();

final int offsetPosition = mAdapterHelper.findPositionOffset(position);

...

final int type = mAdapter.getItemViewType(offsetPosition);

final View view = mViewCacheExtension

.getViewForPositionAndType(this, position, type);

//4. 從 RecycledViewPool 中查找

holder = getRecycledViewPool().getRecycledView(type);

...

//5. 老實建立

holder = mAdapter.createViewHolder(RecyclerView.this, type);

...

dispatchLayoutStep2

// Step 2: Run layout

mState.mInPreLayout = false;

mLayout.onLayoutChildren(mRecycler, mState);