cannot be cast to android.widget.HeaderViewListAdapter源碼分析

cannot be cast to android.widget.HeaderViewListAdapter


       這個異常通常是在setAdapter以後用addHeaderView,removeHeaderView,addFooterView,...等等這一系類方法時出現
並且是在4.3及4.3以前的版本情況下。

       具體看源碼:
       這是4.3的源碼:
	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();
        }
    }

       從源碼中看出:在addHeaderView時會先判斷adapter是不是空和是不是HeaderViewListAdapter類型,如果不是就拋異常,在setAdapter之前是adapter是空的所有不會拋異常

       這是setAdapter的部分源碼:
 public void setAdapter(ListAdapter adapter) {
		.......

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

       ......

        
    }


   /** @hide */
    protected HeaderViewListAdapter wrapHeaderListAdapterInternal(
            ArrayList<ListView.FixedViewInfo> headerViewInfos,
            ArrayList<ListView.FixedViewInfo> footerViewInfos,
            ListAdapter adapter) {
        return new HeaderViewListAdapter(headerViewInfos, footerViewInfos, adapter);
    }

       看了之後是不是很清楚了,在setAdapter會先進行轉換,所以在setAdapter之後不會發生。


       這是4.4的源碼

  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();
            }
        }
    }

        看了上面的下面就很簡單了。在4.4及以後addHeaderView會判斷,然後會直接轉換所以不會出現。

       這是博主的一點見解,如有不足之處請指點。謝謝各位。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章