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会判断,然后会直接转换所以不会出现。
这是博主的一点见解,如有不足之处请指点。谢谢各位。