这是预期的行为,请查看此处的 Android 源代码以获取有关 API 17 的指导,但实际上任何人都可以这样做。相关部分是:
添加一个固定视图以显示在列表顶部。如果 addHeaderView 被多次调用,视图将按照添加的顺序出现。如果需要,使用此调用添加的视图可以成为焦点。注意:在调用 setAdapter 之前调用它。这样 ListView 就可以将提供的光标与一个也将考虑页眉和页脚视图的光标包装起来。
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();
}
}
当您再次添加标头并引发异常时,适配器不为空。要解决您的问题,以下几行就可以了:
setListAdapter(null);
getListView().addHeaderView(mHeader);
setListAdapter(new MyAdapter(getActivity(), items));
我什至不会将此归类为解决方法。我遇到了同样的问题,这对我有用。
显然页脚的处理方式非常不同,请参见此处:
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();
}
}