首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RecyclerView的部分优化

RecyclerView的部分优化

作者头像
提莫队长
发布2021-12-16 10:00:45
7100
发布2021-12-16 10:00:45
举报
文章被收录于专栏:刘晓杰刘晓杰

1.在 onCreateViewHolder 里面写点击事件

这个很好理解,onBindViewHolder会多次调用

2.LinearLayoutManager.setInitialPrefetchItemCount

注意,此方法LinearLayoutManager专属

    public void setInitialPrefetchItemCount(int itemCount) {
        mInitialItemPrefetchCount = itemCount;
    }

mInitialItemPrefetchCount 在这里用到

    @Override
    public void collectInitialPrefetchPositions(int adapterItemCount,
            LayoutPrefetchRegistry layoutPrefetchRegistry) {
        final int direction = fromEnd
                ? LayoutState.ITEM_DIRECTION_HEAD
                : LayoutState.ITEM_DIRECTION_TAIL;
        int targetPos = anchorPos;
        for (int i = 0; i < mInitialItemPrefetchCount; i++) {
            if (targetPos >= 0 && targetPos < adapterItemCount) {
                layoutPrefetchRegistry.addPosition(targetPos, 0);
            } else {
                break; // no more to prefetch
            }
            targetPos += direction;
        }
    }

说白了就是预取操作。collectInitialPrefetchPositions定义当此LayoutManager的RecyclerView嵌套在另一个RecyclerView中时应预取多少内部项目。也就是说只有RecyclerView嵌套才会生效,否则无效

3.setHasFixedSize

setHasFixedSize 会给 mHasFixedSize 赋值,看一下用到的地方

// 第一处
    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {
        if (mLayout == null) {
            defaultOnMeasure(widthSpec, heightSpec);
            return;
        }
        if (mLayout.mAutoMeasure) {
            ......
        } else {
            if (mHasFixedSize) {
                mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
                return;
            }
            // custom onMeasure
            if (mAdapterUpdateDuringMeasure) {
                eatRequestLayout();
                onEnterLayoutOrScroll();
                processAdapterUpdatesAndSetAnimationFlags();
                onExitLayoutOrScroll();

                if (mState.mRunPredictiveAnimations) {
                    mState.mInPreLayout = true;
                } else {
                    // consume remaining updates to provide a consistent state with the layout pass.
                    mAdapterHelper.consumeUpdatesInOnePass();
                    mState.mInPreLayout = false;
                }
                mAdapterUpdateDuringMeasure = false;
                resumeRequestLayout(false);
            }

            if (mAdapter != null) {
                mState.mItemCount = mAdapter.getItemCount();
            } else {
                mState.mItemCount = 0;
            }
            eatRequestLayout();
            mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
            resumeRequestLayout(false);
            mState.mInPreLayout = false; // clear
        }
    }
// 第二处
    private class RecyclerViewDataObserver extends AdapterDataObserver {

        void triggerUpdateProcessor() {
            if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
                RecyclerView.this.postOnAnimation(mUpdateChildViewsRunnable);
            } else {
                mAdapterUpdateDuringMeasure = true;
                requestLayout();
            }
        }
    }

mLayout.mAutoMeasure 默认是false,当然也可以自己设置。当mHasFixedSize是true的时候只会执行onMeasure。另外,每次notifyDataSetChanged的时候只会mUpdateChildViews而不用整个requestLayout。当然,有个前提,adapter的数据变化不会导致RecycleView的大小变化 。

总结,当RecycleView大小固定的时候,setHasFixedSize 为true可以使每次onMeasure和notifyDataSet的时候不用去request整个layout

4.多个RecycleView共用RecycledViewPool

RecycledViewPool 其实并不陌生,就是缓存机制的最后一个pool。如果这里还取不到view就重新create。具体我也写过,参考 RecyclerView的缓存机制和内存优化

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/9/12 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档