Android ListView 源码分析

ListView 的源码实在太多, 重点分析ListView的几个机制

ListView的继承关系

这里写图片描述

可以看出,ListView和GridView的有极大的相似性,对ListView进行缓存,布局等操作都是在AbsListView中完成的.

RecycleBin机制

RecycleBin中的关键字段

RecycleBin将View分为两级,ActiveView和ScrapView,如果当前的view处于可见状态,将它放在ActiveView的数组中,如果ActiveView不可见了,开始将它降级为ScrapView,等待回收.

private RecyclerListener mRecyclerListener;

/**
 * The position of the first view stored in mActiveViews.
 */
 // 第一个ActiveView的下标,通过这个计算数组中的索引
private int mFirstActivePosition;

/**
 * Views that were on screen at the start of layout. This array is populated at the start of
 * layout, and at the end of layout all view in mActiveViews are moved to mScrapViews.
 * Views in mActiveViews represent a contiguous range of Views, with position of the first
 * view store in mFirstActivePosition.
 */
 // ActiveView数组
private View[] mActiveViews = new View[0];

/**
 * Unsorted views that can be used by the adapter as a convert view.
 */
 // ScrapView数组,因为有可能多个ViewType,所以使用二维数组进行存储
private ArrayList<View>[] mScrapViews;

// ViewType的数量,通过这个创建ScrapHeap
private int mViewTypeCount;

private ArrayList<View> mCurrentScrap;

private ArrayList<View> mSkippedScrap;

private SparseArray<View> mTransientStateViews;
private LongSparseArray<View> mTransientStateViewsById;

RecycleBin中的关键方法

fillActiveViews()

RecycleBin当中使用mActiveViews这个数组来存储View,调用这个方法后就会根据传入的参数来将ListView中的指定元素存储到mActiveViews数组当中。

/**
 * Fill ActiveViews with all of the children of the AbsListView.
 *
 * @param childCount The minimum number of views mActiveViews should hold
 * @param firstActivePosition The position of the first view that will be stored in
 *        mActiveViews
 */
void fillActiveViews(int childCount, int firstActivePosition) {
    //针对数据,调整数组大小
    if (mActiveViews.length < childCount) {
        mActiveViews = new View[childCount];
    }
    // 记录ActiveView的首位置
    mFirstActivePosition = firstActivePosition;

    //noinspection MismatchedReadAndWriteOfArray
    final View[] activeViews = mActiveViews;
    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        // 调整LayoutParams
        AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
        // Don't put header or footer views into the scrap heap
        // 除Header,Footer之外其他View将添加到ActiveView数组中
        if (lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
            // Note:  We do place AdapterView.ITEM_VIEW_TYPE_IGNORE in active views.
            //        However, we will NOT place them into scrap views.
            activeViews[i] = child;
            // Remember the position so that setupChild() doesn't reset state.
            lp.scrappedFromPosition = firstActivePosition + i;
        }
    }
}

未完 doing….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值