现在的位置: 首页 > 综合 > 正文

Android中ListView内部代码探析

2013年10月05日 ⁄ 综合 ⁄ 共 2915字 ⁄ 字号 评论关闭

1. ListView是如何添加HeadView的?

一般给ListView添加HeadView代码如下:

View headerView = mInflater.inflate(R.layout.listview_header, null);
mListView.addHeadView(headerView);

下面进入android内部代码探析

    public void addHeaderView(View v) {
        addHeaderView(v, null, true);
    }

    public void addHeaderView(View v, Object data, boolean isSelectable) {

        if (mAdapter != null && ! (mAdapter instanceof HeaderViewListAdapter)) {
            throw new IllegalStateException(
                    "Cannot add header view to list -- setAdapter has already been called.");
        }

        FixedViewInfo info = new FixedViewInfo();
        info.view = v;
        info.data = data;
        info.isSelectable = isSelectable;
        mHeaderViewInfos.add(info);

        // in the case of re-adding a header view, or adding one later on,
        // we need to notify the observer
        if (mAdapter != null && mDataSetObserver != null) {
            mDataSetObserver.onChanged();
        }
    }

可以看到新添加的View,作为数据结构FixedViewInfo的一个成员变量被添加到mHeaderViewInfos中。

而其定义为:

private ArrayList<FixedViewInfo> mHeaderViewInfos = Lists.newArrayList();

可知道,我们可以添加多个HeaderView。

总结:

1. 同一个HeadView不要添加2次。

2. 可以添加多个View。

2. ListView是如何设置Adapter的?

在使用默认的列表项文件android.R.layout.simple_list_item_1时,我们可以用如下方法给一列表设置Adapter。

mListView.setAdapter(new ArrayAdapter<String>(mActivity,
                android.R.layout.simple_list_item_1, mString1));

继续进入源代码:

    public void setAdapter(ListAdapter adapter) {
        if (mAdapter != null && mDataSetObserver != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }

        resetList();
        mRecycler.clear();

        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }

        mOldSelectedPosition = INVALID_POSITION;
        mOldSelectedRowId = INVALID_ROW_ID;

        // AbsListView#setAdapter will update choice mode states.
        super.setAdapter(adapter);

        if (mAdapter != null) {
            mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
            checkFocus();

            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

            mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());

            int position;
            if (mStackFromBottom) {
                position = lookForSelectablePosition(mItemCount - 1, false);
            } else {
                position = lookForSelectablePosition(0, true);
            }
            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);

            if (mItemCount == 0) {
                // Nothing selected
                checkSelectionChanged();
            }
        } else {
            mAreAllItemsSelectable = true;
            checkFocus();
            // Nothing selected
            checkSelectionChanged();
        }

        requestLayout();
    }

根据是否有HeaderView或者FooterView来选择创建HeadViewListAdapter(是ListAdapter子类)或者ListAdapter。
mAdapter.getCount()由用户实现,自己返回自己保存的项的个数的一个列表。

// 截止:2013/7/3 - 16:32 ,下次再添加

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

       

抱歉!评论已关闭.