Android学习之旅

Android RecyleView的常见操作内部原理

2019-09-25  本文已影响0人  pj0579

RecyleView 配合使用的高频使用方法有以下几个
1.notifyDataSetChanged 全部更新
‘这个方法经过调用链最后走到AdapterDataObservable这个被观察者类中的

1.public void notifyChanged() {
            for (int i = mObservers.size() - 1; i >= 0; i--) { 
                // 这里使用了观察者模式  之前进行了一系列的注册
                mObservers.get(i).onChanged();
            }
        }

然后看下onChanged()

2.public void onChanged() {
            assertNotInLayoutOrScroll(null);
            mState.mStructureChanged = true;
            // 这个方法holder.addFlags(ViewHolder.FLAG_UPDATE | ViewHolder.FLAG_INVALID),这个导致RecyleView 的ItemView会重新测量绘制。这种方法会导致一些耗时测量布局的话会出现闪烁情况。通过设置SetHasStableIds(true) 加 getItemId 复写可以解决。
            setDataSetChangedAfterLayout();
            if (!mAdapterHelper.hasPendingUpdates()) {
                // 视图更新
                requestLayout();
            }
        }

2.notifyItemRangeChanged 范围更新

public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            assertNotInLayoutOrScroll(null);
            if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
               // 这个方法默认也是走的requestLayout(); 这方法有个坑爹的地方时 用在下拉刷新时滑动会抛出异常。一般用在加载更多的时候使用。然后是这种刷新方式搭配动画设置false 也可以实现不测量绘制的功能。
                triggerUpdateProcessor();
            }
        }

3.notifyDataSetChangednotifyItemRangeChanged、 的不同之处在于viewHolder.isInvalid()前者为ture

private void scrapOrRecycleView(Recycler recycler, int index, View view) {
            final ViewHolder viewHolder = getChildViewHolderInt(view);
            if (viewHolder.shouldIgnore()) {
                if (DEBUG) {
                    Log.d(TAG, "ignoring view " + viewHolder);
                }
                return;
            }
            if (viewHolder.isInvalid() && !viewHolder.isRemoved()
                    && !mRecyclerView.mAdapter.hasStableIds()) {
                removeViewAt(index);
                recycler.recycleViewHolderInternal(viewHolder);
            } else {
                detachViewAt(index);
                recycler.scrapView(view);
                mRecyclerView.mViewInfoStore.onViewDetached(viewHolder);
            }
        }

4setItemAnimator 给Item设置动画

 public void setItemAnimator(ItemAnimator animator) {
        if (mItemAnimator != null) {
            mItemAnimator.endAnimations();
            mItemAnimator.setListener(null);
        }
        mItemAnimator = animator;
        if (mItemAnimator != null) {
            mItemAnimator.setListener(mItemAnimatorListener);
        }
    }

animator默认是DefaultItemAnimator
dispatchLayoutStep3方法里会执行

// Step 4: Process view info lists and trigger animations
1.mViewInfoStore.process(mViewInfoProcessCallback);
mViewInfoProcessCallback 对应
2.private final ViewInfoStore.ProcessCallback mViewInfoProcessCallback =
            new ViewInfoStore.ProcessCallback() {
                @Override
                public void processDisappeared(ViewHolder viewHolder, @NonNull ItemHolderInfo info,
                        @Nullable ItemHolderInfo postInfo) {
                    mRecycler.unscrapView(viewHolder);
                    animateDisappearance(viewHolder, info, postInfo);
                }
                @Override
                public void processAppeared(ViewHolder viewHolder,
                        ItemHolderInfo preInfo, ItemHolderInfo info) {
                    animateAppearance(viewHolder, preInfo, info);
                }
.......
}

3. void animateAppearance(@NonNull ViewHolder itemHolder,
            @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
        itemHolder.setIsRecyclable(false);
        if (mItemAnimator.animateAppearance(itemHolder, preLayoutInfo, postLayoutInfo)) {
            postAnimationRunner();
        }
    }

postAnimationRunner最后调用
4. private Runnable mItemAnimatorRunner = new Runnable() {
        @Override
        public void run() {
            if (mItemAnimator != null) {
                mItemAnimator.runPendingAnimations();
            }
            mPostedAnimatorRunner = false;
        }
    };

5.runPendingAnimations 
此方法根据逻辑执行相关动画
上一篇 下一篇

猜你喜欢

热点阅读