深入理解自定义ListView

深入理解自定义ListView

ListView原理

  1. 他是一个系统的原生控件,用列表的形式来显示内容。如果内容过过有1000条左右,我们可以通过手势的上下滑动来查看数据。ListView也不是爆出OOM(out of memery)错误。下面是类的继承机构
    深入理解自定义ListView

  2. 我们给ListView装配数据的时候,要给他定义一个适配器Adapter,为什么要定义呢?
    深入理解自定义ListView
    我的理解是给ListView一个通道,在和我们的数据之间建立一个连接,这样当ListView需要展现什么的数据,什么样的布局的时候我们就可以通过自己定义的Aapter中的getView(parament...)方法来获取到我们要加入到ListView的视图。

  3. RecycleBin机制,它是写在AbsListView中的一个内部类,所以所有继承自AbsListView的子类,也就是ListViewGridView,都可以使用这个机制,
    主要作用,通过一系列方法,实现View的缓存机制,

fillActiveViews(...)这个方法接收两个参数,第一个参数表示要存储的view的数量,第二个参数表示ListView中第一个可见元素的position值。RecycleBin当中使用mActiveViews这个数组来存储View,调用这个方法后就会根据传入的参数来将ListView中的指定元素存储到mActiveViews数组当中。

getActiveView(...) 用于根据参数*position获取mActiveViews当中的View。需要注意的是当View一旦被获取以后,下次再获取同样的位置就将会是null。所以mActiveView不能重复利用.\。

addScrapView(...) 用于将一个废弃的View缓存。当我们View将要废掉以后(比如滚出屏幕)。那么就会调用这个方法进行缓存。RecycleBin当中使用mScrapViewsmCurrentScrap这两个List来存储废弃View

getScrapView(...)用于在mScrapViews中末尾取出一个废弃View,

setViewTypeCount() 我们都知道Adapter当中可以重写一个getViewTypeCount()来表示ListView中有几种类型的数据项,而setViewTypeCount()方法的作用就是为每种类型的数据项都单独启用一个RecycleBin缓存机制。实际上,getViewTypeCount()方法通常情况下使用的并不是很多,所以我们只要知道RecycleBin当中有这样一个功能就行了.

  1. 如何绘制View.我们通过自定义Adapter中重写getView(),获取到要显示的View,当我们装载到ListView的时候,是通过onMeasure()来测量大小。onLayout()用于确定View的布局,onDraw来绘制View显示到界面上。但是ListView不负责绘制,是由他的子元素进行绘制的。

5.滑动加载更多数据ListView有滑动的监听机制onTouchEvent()来监听手势的滑动。因为滑动是通用的机制所以写在AbsListView当中,所以GridView也可以使用这个机制。

View obtainView(int position, boolean[] isScrap) {  
isScrap[0] = false;
View scrapView;
scrapView = mRecycler.getScrapView(position);
View child;
if (scrapView != null) {
child = mAdapter.getView(position, scrapView, this);
if (child != scrapView) {
mRecycler.addScrapView(scrapView);
if (mCacheColorHint != 0) {
child.setDrawingCacheBackgroundColor(mCacheColorHint);
}
} else {
isScrap[0] = true;
dispatchFinishTemporaryDetach(child);
}
} else {
child = mAdapter.getView(position, null, this);
if (mCacheColorHint != 0) {
child.setDrawingCacheBackgroundColor(mCacheColorHint);
}
}
return child;
}

通过读取上面的代码我们可以理解到:如果RecycleBin对应mRecycler中获mActiveView储存当中末尾获取一个废弃的View

通过如下代码传递一个scrapView

child = mAdapter.getView(position, scrapView, this);

如果为null的话。那么就会通过该段代码

child = mAdapter.getView(position, null, this);

可以看到mAdapter就是我们自己定义的适配器。所以obtainView类会通过不断回收废弃的Veiw通过getView(...)来获取数据,所以就不会爆出OOM错误了。因为在Listview当中,通过RecycleBin的机制不断回收,具体原理如下图

深入理解自定义ListView

适配器的优化参考我自己写的

自定义适配器优化

上一篇:zabbix批量添加被监控windows客户端


下一篇:FFmpeg源代码简单分析:libavdevice的gdigrab