ListView的回收机制

本文详细解析了ListView的回收机制,包括RecycleBin类的关键成员变量和方法,以及在ListView中的调用分析。

一、RecycleBin 

  ListView的回收机制是通过RecycleBin来完成的,这个类在AbsListView(AbsListView的子类有GridView和ListView)中,下面对这个类的关键成员变量和方法进行解释:

1、变量mActiveViews:是一个view数组,用来存储屏幕上显示的View。

2、变量mScrapViews:是一个ArrayList的数组,用来存储滑出屏幕后的View。

3、方法fillActiveViews(int childCount, int firstActivePosition) :存储ListView中可见的Item的view,在notifyDataSetChanged方法执行后,假如界面中item的数据没有改变则把View添加到mActiveViews集合中。在ListView中的layoutChildren方法里面调用。

4、方法getActiveView:获取ListView中可见的item中的view,在notifyDataSetChanaged方法执行后,如果数据没有改变则获取这个view。在makeAndAddView方法中调用。

5、方法addScrapView:添加view到回收的mScrapViews集合中,当item滑出屏幕后执行。在layoutChildren方法中调用。</p><p>6、方法getSrapView:从回收中的集合获取一个view对象,当屏幕有新的item展示的时候会调用。在AbsListView中的obtainView中调用。

6、方法getSrapView:从回收中的集合获取一个view对象,当屏幕有新的item展示的时候会调用。在AbsListView中的obtainView中调用。

7、方法retrieveFromScrap:在getScrapView中调用,从回收的view集合里面查找view。这里有三种情况:

(1)假如ListView刚刚展示五个view,当我们往下滑动的时候,第六个view展示,这个时候mScrapViews中没有存储任何的View对象,所以返回null。

(2)当用户继续向下滑动第一个view不可见,这个时候会添加到mScrapViews集合里面去,如果上滑,第一个view又重新展示,这个时候会通过位置来拿到mCrapViews中的view。

(3)接着(2)中向下滑动第七个view展示,那么就会获取mScrapViews集合中最后一个View。

二、在ListView中的调用分析

接下来通过mLayoutMode布局类型来获取item里面的view,其中布局类型可以从上往下绘制,从中间绘制,从指定的位置绘制等等。都会调用fill开头的方法,从顶部绘制fillFromTop,指定位置绘制fillFromSelection,中间布局fillFromMiddle等。其中都会调用makeAndAddView这个方法来获取view对象。下面看这个方法:

2、makeAndAddView

  数据没有变的时候就从RecycleBin对象里面的mActiveViews集合获取view,否则从回收的集合mScrapViews里面获取,具体调用obtain方法。这里面其实做了一个优化,就是数据更新的时候假如数据没有变直接从集合里面取出view对象即可。

       if (!mDataChanged) {
            // Try to use an existing view for this position
            child = mRecycler.getActiveView(position);
            if (child != null) {
                // Found it -- we're using an existing child
                // This just needs to be positioned
                setupChild(child, position, y, flow, childrenLeft, selected, true);

                return child;
            }
        }

        // Make a new view for this position, or convert an unused view if possible
        child = obtainView(position, mIsScrap);
3、obtainView方法

  这个方法从回收的view中 获取view,假如没有则重新创建新的view。scrapView = mRecycler.getScrapView(position); 从RecycleBin获取回收的View

       if (scrapView != null) {
            child = mAdapter.getView(position, scrapView, this);

            if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
                child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
            }

            if (child != scrapView) {
                mRecycler.addScrapView(scrapView, position);
                if (mCacheColorHint != 0) {
                    child.setDrawingCacheBackgroundColor(mCacheColorHint);
                }
            } else {
                isScrap[0] = true;

                // Clear any system-managed transient state so that we can
                // recycle this view and bind it to different data.
                if (child.isAccessibilityFocused()) {
                    child.clearAccessibilityFocus();
                }

                child.dispatchFinishTemporaryDetach();
            }
        } else {
            child = mAdapter.getView(position, null, this);

            if (child.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
                child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
            }

            if (mCacheColorHint != 0) {
                child.setDrawingCacheBackgroundColor(mCacheColorHint);
            }
        }
   然后通过adapter的getView方法拿到回收的View或者重新创建一个view对象。

4、onTouchEvent方法

  当我们的手指上下滑动的时候,RecycleBin是怎么工作的呢?这个时候会执行onTouch开头的方法,如ACTION_MOVE时候执行onTouchMove,追踪源码到trackMotionScroll方法,到fillGap方法。fillGap在ListView中实现的,然后调用fillDown或者fillUp方法。在fill开头的方法里面会调用makeAndAddView方法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值