ListView性能优化系列之二

[align=center][size=large][b]ListView性能优化系列之二[/b][/size][/align]
上一节从应用层面给出了ListView性能优化的方法,这一节将从ListView源码中探寻真谛。
[b]下集预告:[/b]这一小节讲垃圾回收站,下一个小节讲这个回收站具体是怎么用的,以及adapter中的getView方法是如何拿到回收站的内容的。

[b]下面是ListView的继承关系[/b]
[img]http://dl.iteye.com/upload/attachment/0074/6119/fe7179bd-c0b7-3a32-98a1-0aa49c8826e1.jpg[/img]
ListView继承自AbsListView,而在AbsListView中的RecycleBin就是上一节中View复用的关键。下面就对RecycleBin进行分析
[size=large][b]RecycleBin[/b][/size]
[b]1、RecycleBin中的数据结构[/b],这些数据结构就是在垃圾回收站堆放的一个个垃圾桶。

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;

[b]2、RecycleBin中的重要主要方法分析[/b]

//从回收站中获取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);
}
}

[size=large][b]总结:[/b][/size]贴了一大堆的代码,写了一大堆的注释,其实RecycleBin就是一个大的垃圾回收站,回收[color=red]所有可以被回收的视图[/color](源码过滤掉了不需要回收的视图,包括header和footer)。RecycleBin提供了一系列的方法对回收站进行管理。这里只是简单介绍了两个方法,其他方法有兴趣的同学可以自己看看。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值