RecycleBin()方法:
fillActiveViews(): 两个参数: 要存储的view的数量, ListView中第一个可见元素的position值。 使用 mActiveViews这个数组来存储View,根据传入参数将ListView指定元素存入数组。(为了将view进行缓存)
getActivityViews(): 从mActiveViews数组中获取数据,接受position参数,表示在ListView中的位置,方法会将position转化成mActiveViews数组的下标值。 注意:数组中View只能被获取一次,之后便会被删除,再次获取就回返回null,不能重复利用。
addScrapView(): 接受View参数,将废弃的View进行缓存(如滚出屏幕),使用mScrapView和mCurrentScrap两个List来存储。
getScrapView(): 废弃缓存中的VIew是没有顺序的,方法直接从mCurrentScrap中获取尾部一个scrap view进行返回。
setViewTypeCount(): 在Adapter中可以写getViewTypeCount()来表示ListView中有几种类型的数据,而该方法将每种数据项都单独启用一个RecycleBin缓存机制。(使用不多)
view执行流程(未详读):onMeasure()测量view的大小,onLayout()确定View的布局,onDraw()绘制在界面上。主要功能在onLaytou中进行。
onLayout()方法在ListView的父类AbsListView中,(boolean changed, int l, int t, int r, int b),主要进行判断,当ListView的大小或者位置发生了变化,changed变成true,要求子布局重绘。最后调用layoutChildren()方法,进行子元素布局,此方法在ListView的layoutChildren()中进行。
layoutChildren():如数据改变,dataChange,true时则调用addScrapView,...false则调用fillActiveViews(),然后根据mLayoutMode的值来决定布局模式,开始布局:调用fillFromTop(),本身只是判断mFirstPosition的合法性(看是否大于0好像。。),再调用fillDown(int pos, int nextTop),参数分别为mFirstPosition,和第一个子元素顶部距离ListView顶部的像素值,它当中的调用makeAndAddView()方法,会尝试从Recycle中获取一个active view,如果没有会继续向下执行obtainView()再次获取,此方法会返回一个View,将获取到的传入setupChild()。
obtainView()会先调用getScrapView()获取废弃View,没有就会返回null,继续执行mAdapter的getView()方法,这就是适配器了,我们会显式的操作这里,第一次layout过程LayoutInflater的inflate()方法加载,会相对耗时。
setupChild() 在这里调用addViewInLayout()将view添加到ListView,然后fillDown()加载一个屏幕的数据就跳出来了。
一般会进行至少两次Layout过程,即onMeasure(),onLayout()的过程,为避免出现重复数据,调用了detachAllViewsFromParents()方法,将ListView中的子View全部删除,然后调用fillActiveViews()方法缓存的View,不会再次调用inflate影响效率。
第二次会调用fillSpecific()的方法,跟fillDown类似。再次执行makeAndAddView()方法这次拿到了View,节省了时间,再次执行setupChild()方法,其中执行到attachViewParent()方法,不再执行addViewInLayout(),从detach状态,到attach状态。再次显示出来。
上滑加载数据:
在onTouchEvent方法中进行的,队形ACTION_MOVE动作,移动以后调用trackMotionScroll()方法,向上滑动会调用多次,通过判断手指发生事件的位置的距离变化,判断View的边界与ListView的边界,超出则移除屏幕,加入到废弃缓存,再次进行detach,只要没有用就不保留,在调用offsetChildTopAndBottom()方法让所有View进行位移,实现移动效果,如果第一个或最后一个View移入屏幕,就调用fillGap()方法,在其中会判断使用fillUp或fillDown方法,再次makeAndAddView(),因为不能复用没所以缓存中是没有了,调用obtainView(),不过现在废弃的View有了,就可以调用这里的了,就是这么神奇。这里就是getView(, View convertView, ),先判断这个参数是不是null,才决定调用inflate()。然后就可以显示了,我觉得像三条主线路~~~~~