ListView性能优化系列之二
上一节从应用层面给出了ListView性能优化的方法,这一节将从ListView源码中探寻真谛。
下集预告:这一小节讲垃圾回收站,下一个小节讲这个回收站具体是怎么用的,以及adapter中的getView方法是如何拿到回收站的内容的。
下面是ListView的继承关系
ListView继承自AbsListView,而在AbsListView中的RecycleBin就是上一节中View复用的关键。下面就对RecycleBin进行分析
RecycleBin
1、RecycleBin中的数据结构,这些数据结构就是在垃圾回收站堆放的一个个垃圾桶。
private RecyclerListener mRecyclerListener; // 第一个存放在mActiveViews中的view的位置. private int mFirstActivePosition; // 用来存放屏幕可见区域的view private View[] mActiveViews = new View[0]; /** * 这个ArrayList就是adapter中getView方法中的参数convertView的来源 * 注意:这里是一个数组,因为如果adapter中数据有多种类型 * 那么就会有多个垃圾桶(对比垃圾分类)来放每一种垃圾 */ private ArrayList<View>[] mScrapViews; /* * view的类型数,列表中可能有多种数据类型(根据adapter提供的数据) *比如用户真正关心的数据,或者是分割符 */ private int mViewTypeCount; /* * 其实就是指向mScrapViews[0]的一个引用,也就是第一种view对应的垃圾桶 */ private ArrayList<View> mCurrentScrap;
2、RecycleBin中的重要主要方法分析
//从回收站中获取view View getScrapView(int position) { ArrayList<View> scrapViews; if (mViewTypeCount == 1) {//只有一种视图类型 scrapViews = mCurrentScrap; int size = scrapViews.size(); if (size > 0) { return scrapViews.remove(size - 1);//数据返回的同时,回收站中的内容被删除了 } else { return null; } } else {//多种数据类型 int whichScrap = mAdapter.getItemViewType(position); if (whichScrap >= 0 && whichScrap < mScrapViews.length) { scrapViews = mScrapViews[whichScrap]; int size = scrapViews.size(); if (size > 0) { return scrapViews.remove(size - 1); } } } return null; }
/** * 将视图放入回收站 * @param scrap */ void addScrapView(View scrap) { AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap .getLayoutParams(); if (lp == null) { return; } int viewType = lp.viewType; if (!shouldRecycleViewType(viewType)) {//过滤掉不需要回收的view if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) { removeDetachedView(scrap, false);//分发托管事件以及通知 } return; } if (mViewTypeCount == 1) {//只有一种视图类型 scrap.dispatchStartTemporaryDetach(); mCurrentScrap.add(scrap); } else {//有多种视图类型 scrap.dispatchStartTemporaryDetach(); mScrapViews[viewType].add(scrap); } if (mRecyclerListener != null) {//监听器回调 mRecyclerListener.onMovedToScrapHeap(scrap); } }
总结:贴了一大堆的代码,写了一大堆的注释,其实RecycleBin就是一个大的垃圾回收站,回收 所有可以被回收的视图(源码过滤掉了不需要回收的视图,包括header和footer)。RecycleBin提供了一系列的方法对回收站进行管理。这里只是简单介绍了两个方法,其他方法有兴趣的同学可以自己看看。