RecycleBin类(回收类)
先详细了解一下这个回收类(listview中多次调用,关键类)
1.AbsListView的内部类
2.全局变量
private View[] mActiveViews = new View[0];可见view数组即在当前屏幕上的所有view
private int mFirstActivePosition;当前屏幕上第一个可见的item的position
private ArrayList<View> mCurrentScrap;回收的view数组即被移除的view(listview中只有一种类型item)
private ArrayList<View>[] mScrapViews;回收的view数组(listview中有多种类型item)
private int mViewTypeCount;listview中item的类型数量
3.方法
1.setViewTypeCount(int count);初始化mViewTypeCount,mScrapViews,mCurrentScrap
2.markChildrenDirty();使子布局变脏即让mScrapViews或mCurrentScrap里的view重新布局
3.fillActiveViews(int childCount, int firstActivePosition);填满mActiveViews
定义firstActivePosition(当前屏幕上第一个可见的item的position),
定义mActiveViews()数组(除了头部和底部所有的可见view)
4.getActiveView(int position);获取对应position的view,拿到此view把mActiveViews()数组中的此view置空(回收内存)
5.addScrapView(View scrap, int position);
把除了头部和底部的所有view添加到mCurrentScrap(type==1)或mScrapViews(type>1)中
mRecyclerListener.onMovedToScrapHeap(scrap);监听所有被回收view(Transient类型的view另作处理),不只是这个方法有调用
6.getScrapView(int position);获取被回收的view(复用)并且获取到后从mScrapViews移除
retrieveFromScrap(ArrayList<View> scrapViews, int position);继续获取被回收的view,从scrapViews中获取view。
a.params.scrappedFromPosition == position和id == params.itemId这俩个判断实际是一个意思只不过取法不同;直接返回position的view,scrappedFromPosition 是addScrapView的position
b.不符合上面a中的两个条件就取mScrapViews中的最后一个view
c.如果mScrapViews为空或size为0,则返回null(会走adapter.getView()重新渲染一个新的item)
eg:
当前listview第一次加载只能看到10个item(此时mScrapViews为null),
1.向上滑动半个item要显示第11个item的一半,那么mCurrentScrap还是null(因为第一个item没有被回收,还有半个),就会走adapter.getView获取新的view
2.再向上滑动半个item(就是一整个了),那么这个item就会回收到mCurrentScrap中,此时显示的第11个item就是从mCurrentScrap获取到的(但是他不是scrappedFromPosition == position的view,而是最后一个view)
而此时mCurrentScrap为空
感谢niknowzcd,博主地址https://www.jianshu.com/p/0ec7b56d974e
关注本人公众号获取更多干货.