zoukankan      html  css  js  c++  java
  • 从源代码上分析ListView的addHeaderView和setAdapter的调用顺序

    ListView想要加入headerview的话,就要通过addHeaderView这种方法,然后想要为ListView设置数据的话,就要调用setAdapter方法了。可是,在调用addHeaderView和setAdapter的顺序上,有时会爆出java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.的异常。这是由于我们在addHeaderView之前调用了setAdapter。所以,在这里,建议setAdapter须要在addHeaderView和addfooterView之后调用。这样就安全了。以下,我们来看看源代码吧。看看到底是什么原因造成的。

    Android-18(4.3)的addHeaderView源代码:

    public void addHeaderView(View v, Object data, boolean isSelectable) {
            final FixedViewInfo info = new FixedViewInfo();
            info.view = v;
            info.data = data;
            info.isSelectable = isSelectable;
            mHeaderViewInfos.add(info);
     
            // Wrap the adapter if it wasn't already wrapped.
            if (mAdapter != null) {
                if (!(mAdapter instanceof HeaderViewListAdapter)) {
                    mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
                }
     
                // In the case of re-adding a header view, or adding one later on,
                // we need to notify the observer.
                if (mDataSetObserver != null) {
                    mDataSetObserver.onChanged();
                }
            }
    }

    Android-17(4.2)的addHeaderView的源代码:

    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();
            }
    }
    在上面,我们能够对照出代码中的处理的不同。在17版本号中,仅仅要adapter不为空的话,那就直接会抛出异常,而这个异常恰好就是我们文章开头说到的异常。在18版本号中,假设adapter不为空的话,则会新建一个adapter,这个adapter会包括了headerview和footerview以及我们传进来的原来的adapter。这是在18版本号以后做的一个处理。尽管有了处理,可是建议大家还是依照上面说的调用顺序来使用addHeaderView,addFooterView和setAdapter吧。

  • 相关阅读:
    ZOJ Problem Set–2417 Lowest Bit
    ZOJ Problem Set–1402 Magnificent Meatballs
    ZOJ Problem Set–1292 Integer Inquiry
    ZOJ Problem Set–1109 Language of FatMouse
    ZOJ Problem Set–1295 Reverse Text
    ZOJ Problem Set–1712 Skew Binary
    ZOJ Problem Set–1151 Word Reversal
    ZOJ Problem Set–1494 Climbing Worm
    ZOJ Problem Set–1251 Box of Bricks
    ZOJ Problem Set–1205 Martian Addition
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4307119.html
Copyright © 2011-2022 走看看