Android知识点整理-RecyclerView

234 阅读3分钟

RecyclerView

RecyclerView的缓存机制。如何优化?

对于新增或删除数据通过DiffUtil,来进行局部数据刷新 image.png www.jianshu.com/p/0a928ae58…

www.jianshu.com/p/1853ff1e8…

Recycler是怎么进行回收和复用的

blog.csdn.net/m0_37796683…

  1. RecyclerVIew的回收原理 在RecyclerView重新布局onLayoutChildren()或者填充布局fill()的时候,会先把必要的item与屏幕分离或者移除,并做好标记,保存到list中,在重新布局时,再将ViewHolde拿出来重新一个个放到新的位置上去。

(1)如果是RecyclerView不滚动情况下缓存(比如删除item),重新布局时,把屏幕上的ViewHolder与屏幕分离下来,存放到Scrap中,即发生改变的ViewHolder缓存到mChangedScrap中,不发生改变的ViewHolder存放到mAttachedScrap中;剩下ViewHolder的会按照mCachedViews>RecycledViewPool的优先级缓存到mCachedViews或者RecycledViewPool中。

(2)如果是RecyclerVIew滚动情况下缓存(比如滑动列表),在滑动时填充布局,先移除滑出屏幕的item,第一级缓存mCachedViews优先缓存这些ViewHolder,但是mCachedViews最大容量为2,当mCachedViews满了以后,会利用先进先出原则,把旧的ViewHolder存放到RecycledViewPool中后移除掉,腾出空间,再将新的ViewHolder添加到mCachedViews中,最后剩下的ViewHolder都会缓存到终极回收池RecycledViewPool中,它是根据itemType来缓存不同类型的ArrayList,最大容量为5。

  1. RecyclerVIew的复用原理 至此,已经有五个缓存RecyclerView的池子,mChangedScrap、mAttachedScrap、mCachedViews、mViewCacheExtension、mRecyclerPool,除了mViewCacheExtension是系统提供给开发者拓展的没有用到之外,还有四个池子是参与到复用流程中的。

当RecyclerView要拿一个复用的ViewHolder时,如果是预加载,则会先去mChangedScrap中精准查找(分别根据position和id)对应的ViewHolder,如果有就返回,如果没有就再去mAttachedScrap和mCachedViews中精确查找(先position后id)是不是原来的ViewHolder,如果是说明ViewHolder是刚刚被移除的,如果不是,则最终去mRecyclerPool找,如果itemType类型匹配对应的ViewHolder,那么返回实例,让它重新绑定数据,如果mRecyclerPool也没有返回ViewHolder才会调用createViewHolder()重新去创建一个。

LayoutManager怎么进行布局的

--

如何返回不一样的Item

在Adapter重写getItemViewType,在createViewHolder根据不同的type创建不同类型的viewholder

如何给RecyclerView加下拉刷新&上拉加载

下拉刷新:SwipeRefreshLayout

上拉加载:paging3中继承PagingSource重写load方法

ListView或者RecyclerView在显示新闻数据的时候,出现图片错位,可能的原因有哪些&如何解决?

原因:glide图片异步加载,RecyclerView划出屏幕,viewholder复用导致

解决:使用setTag()方式。但是,Glide图片加载也是使用这个方法,所以需要使用setTag(key,value)方式进行设置,这种方式是不错的一种解决方式,注意取值的时候应该是getTag(key)这个方法,当异步请求回来的时候对比下tag是否一样,再判断是否显示图片,我使用的是position设置tag.

image.png

 @Override
    public void onBindViewHolder(final VideoViewHolder holder, final int position) {
        holder.thumbView.setTag(R.id.tag_dynamic_list_thumb, position);
        Glide.with(mContext)
                .load(picUrl)
                .error(R.drawable.video_thumb_loading)
                .into(new SimpleTarget<GlideDrawable>() {
                    @Override
                    public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation {
                        if (position != (Integer) holder.thumbView.getTag(R.id.tag_dynamic_list_thumb))
                            return;
                            holder.thumbView.setImageDrawable(glideDrawable);
                    }

                    @Override
                    public void onStart() {
                        super.onStart();
                        holder.thumbView.setImageResource(R.drawable.ic_loading);
                    }
            });
    }

RecyclerView联系人列表如何实现A-Z快速定位

scrollToPosition(int)或者 github.com/YoKeyword/I…

RecyclerView中的观察者模式

--

ViewHolder为什么要被声明成静态内部类

网上好多错误答案,个人还是觉得不应该被声明成为静态内部类。

通过使用静态,它只是意味着你可以在其他适配器中重新使用MyViewholder。如果你确定你只在那个适配器中需要MyViewholder,那么你应该让它成为非静态的。

如果你在其他适配器中也需要它,那么最好是把它完全创建为一个单独的类,而不是一个嵌套类。