ListView缓存

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27623401/article/details/79387830

一、什么是ListView

        ListView是一个能数据集合以动态滚动的方式展示到用户界面上的View。

二、ListView适配器模式

        ListView适配器Adapter是一种MVC的模式,Adapter就是为了把数据和View进行分离开来。Adapter模式最重要的就是让ListView绘制他需要相应的数据到他的Item上。getView方法中就是为了绘制每一个Item用的,在ListView开始绘制的时候,首先会调用getCount方法,getCount方法返回的就是ListView数据的长度,根据这个长度会调用getView方法用来绘制每一个Item。也就是说ListView中有多少个Item就会调用多少次getView方法来绘制。

三、ListView的RecyclerBin机制

        当数据集很大的时候,那么绘制了如此之多的Item,每一次滑动会出现OOM吗?这个问题就是ListView的RecyclerBin机制出现的原因。

        在ListView所继承的AbsListView中有一个RecyclerBin内部类,下面是RecyclerBin中几个重要的变量方法

        View [] mActiveViews 变量是指ListView中屏幕上可见的View。

        ArrayList<View>[] mScrapViews 变量是指在屏幕外被废弃的View的集合。

        ArrayList<View> mCurrentScrap 当前废弃View的集合,就是说当前被滑出去的View,将要被废弃的View。

        

        setViewTypeCount()这个方法就是为了为每一个类型的Item建立一个RecyclerBin机制,ListView中可以设定不同的Item类型,对每一个类型的Item都设置RecyclerBin机制

         

        fillActiveViews()方法,childCount参数表示是要存储View的数量,firstActivePosition参数表示ListView当中第一个可见元素的position值。调用这个方法后,就会根据参数把指定的View存储到mActiveViews当中。

        

        getActiveView方法顾名思义就是获取屏幕上所显示的View,position参数就是表示元素在ListView当中显示的位置。这个方法神奇的地方是他会将position这个值转成mActiveViews数组的下标值,当它他调用这个方法后对应的View在activeVIews中就会被设为null, 就是下次获取同样位置的View他也将会变为null,所以mActiveViews屏幕上的View是不能被重复利用的。

        还有一个addScrapView方法,名字上看就知道,当view刚刚被滑出屏幕以后机会被添加到mScrapViews 这个数组当中。 RecyclerBin机制就是调用这个方法来进行缓存的。


上图就解析了为什么ListView如果存储了大量数据也不造成OOM的原因,只有屏幕上这些元数1~5会储存在内存当中,其他移除屏幕外的都会被保存在RecyclerBin机制当中。

四、ListView的优化

        convertView重用/Viewholder

        

        convertView就是缓存的View,可以判断缓存中如果不存在我们才去创建。

        ViewHolder

        

        利用ViewHolder可以减少每次findViewById的次数,view是一个二叉树的结构,所以每次找到的话都会非常耗时。特别是控件多的时候。

        在ListView滑动时,尽量不要有任何操作,如果非得操作,就添加个监听滑动事件,等滑动结束后在进行一系列操作。

        在Item布局中也尽量少用半透明的控件,因为半透明的控件比不透明的控件更耗时。

猜你喜欢

转载自blog.csdn.net/qq_27623401/article/details/79387830