This is intended behaviour, take a look at the Android source code here for guidance on API 17, but really any will do. The relevant part is:
Add a fixed view to appear at the top of the list. If addHeaderView is
called more than once, the views will appear in the order they were
added. Views added using this call can take focus if they want. NOTE:
Call this before calling setAdapter. This is so ListView can wrap the
supplied cursor with one that will also account for header and footer
views.
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."); // Edit: SK9 wrapped this.
}
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();
}
}
The adapter is not null when you come to add the header again and an exception is being raised. To resolve your issue, something along the following lines will do just fine:
setListAdapter(null);
getListView().addHeaderView(mHeader);
setListAdapter(new MyAdapter(getActivity(), items));
I wouldn't even classify this as a workaround. I encountered the same problem and this worked for me.
Apparently footers are treated very differently, see here:
public void addFooterView(View v, Object data, boolean isSelectable) {
// NOTE: do not enforce the adapter being null here, since unlike in
// addHeaderView, it was never enforced here, and so existing apps are
// relying on being able to add a footer and then calling setAdapter to
// force creation of the HeaderViewListAdapter wrapper
FixedViewInfo info = new FixedViewInfo();
info.view = v;
info.data = data;
info.isSelectable = isSelectable;
mFooterViewInfos.add(info);
// in the case of re-adding a footer view, or adding one later on,
// we need to notify the observer
if (mAdapter != null && mDataSetObserver != null) {
mDataSetObserver.onChanged();
}
}