ListView缓存机制

ListView在RecyclerView出现之前是列表使用最多的控件,它自然是有它的优势的,而ListView的缓存机制也是面试常考的问题之一。下面就简单说一说ListView的缓存机制。

一、RecycleBin缓存机制

RecycleBin是写在AbsListView中的,而ListView继承于AbsListView,也自然继承了这个机制。

变量

1、private View[] mActiveViews : 缓存屏幕上可见的view

2、private int mViewTypeCount : ListView中子布局不同类型的类型总数

3、ArrayList<View>[] mScrapViews : ListView中所有的废弃缓存。这是一个数组,每一种布局类型的view都有一个自己的arraylist缓存。

4、ArrayList<View> mCurrentScrap : 当前childView布局类型下的缓存

方法

1、 void fillActiveViews() : 此方法将listview中指定元素存放到mActiveViews中

2、View getActiveView() : 从mActiveViews中取出指定元素,取出view后,该位置元素将被置空。

3、addScrapView() : 将一个废弃view置入缓存。如果布局类型只有一项,则直接存入mCurrentScrap中,如果有多项,从mScrapViews中找到对应废弃缓存并存储。

4、View getScrapView() : 与addScrapView对应,从相应类型的缓存中,取出view。

5、setViewTypeCount() : 为mViewTypeCount设置布局类型总数,同时为每一种布局类型启动一个RecycleBin机制。

RecycleBin缓存机制原理,当一个view滑出界面时,会调用addScrapView方法,将view缓存,当一个view进入页面时,会调用getScrapView方法获取一个view。adpater中的getView方法里的convertView正是取出来的view,如果为空就说明缓存中已经没有view了,需要我们inflate一个。之后就是对holder的操作。

二、如何区分布局类型

那么listview是如何区分缓存的view是哪一种类型呢。看下面两张图。



第一张是设置布局类型数量的方法,可以看到设置完布局类型数量后,为每一种布局类型都创建了一个arrayList存放view。而图二中,mAdapter的getItemViewType方法,便获取到了这个view的类型。看到这里也明白了,为什么getItemViewType的返回值一定要小于getItemTypeCount,因为是以这个值为脚标,从arraylist数组中取值。至于这个LayoutParams中为什么会有viewType,那是因为absListView自己重写了LayoutParams,增加了这个变量,用于区分布局类型。


好了,到这里大多数的疑问就都解决了吧。唯一不太清楚的可能就是滑动时候的触发事件了,在那些事件里,调用了listview的这一套recycleBin缓存机制。有兴趣的读者,自行去读源码吧。

猜你喜欢

转载自blog.csdn.net/kongou/article/details/80791022
今日推荐