错误提示
使用mListView.addHeaderView()时报以下错误
Cannot add header view to list – setAdapter has already been called
在SDK Android 4.0.1(不包含4.0.1)以前
ListView.addHeaderView()的源码为:
276 public void More ...addHeaderView(View v, Object data, boolean isSelectable) {
277
278 if (mAdapter != null) {
279 throw new IllegalStateException(
280 "Cannot add header view to list -- setAdapter has already been called.");
281 }
282
283 FixedViewInfo info = new FixedViewInfo();
284 info.view = v;
285 info.data = data;
286 info.isSelectable = isSelectable;
287 mHeaderViewInfos.add(info);
288 }
在SDK Android 4.0.1(包含4.0.1) ~ SDK Android 4.3.1(包含4.3.1)
ListView.addHeaderView()的源码为:
252 public void More ...addHeaderView(View v, Object data, boolean isSelectable) {
253
254 if (mAdapter != null && ! (mAdapter instanceof HeaderViewListAdapter)) {
255 throw new IllegalStateException(
256 "Cannot add header view to list -- setAdapter has already been called.");
257 }
258
259 FixedViewInfo info = new FixedViewInfo();
260 info.view = v;
261 info.data = data;
262 info.isSelectable = isSelectable;
263 mHeaderViewInfos.add(info);
264
265 // in the case of re-adding a header view, or adding one later on,
266 // we need to notify the observer
267 if (mAdapter != null && mDataSetObserver != null) {
268 mDataSetObserver.onChanged();
269 }
270 }
在SDK Android 4.4(包含4.4)以后
ListView.addHeaderView()的源码为:
260 public void More ...addHeaderView(View v, Object data, boolean isSelectable) {
261 final FixedViewInfo info = new FixedViewInfo();
262 info.view = v;
263 info.data = data;
264 info.isSelectable = isSelectable;
265 mHeaderViewInfos.add(info);
266
267 // Wrap the adapter if it wasn't already wrapped.
268 if (mAdapter != null) {
269 if (!(mAdapter instanceof HeaderViewListAdapter)) {
270 mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
271 }
272
273 // In the case of re-adding a header view, or adding one later on,
274 // we need to notify the observer.
275 if (mDataSetObserver != null) {
276 mDataSetObserver.onChanged();
277 }
278 }
279 }
可以看到SDK Android 4.4及以后,ListView.addHeaderView()就不在抛异常了。源码中的注释也有也是,请看:
Note: When first introduced, this method could only be called before setting the adapter with setAdapter(ListAdapter).
Starting with android.os.Build.VERSION_CODES.KITKAT, this method may be called at any time.
有一种特殊情况,ListView.addHeaderView()在在SDK Android 4.0.1(不包含4.0.1)以前常抛异常,而在在SDK Android 4.0.1(包含4.0.1) ~ SDK Android 4.3.1(包含4.3.1)间基本不抛了,这是为什么呢?请自行查看上面的SDK Android 4.0.1(包含4.0.1) ~ SDK Android 4.3.1(包含4.3.1)的ListView.addHeaderView()源码以及下面各个版本ListView.setAdapter()方法:
public void More ...setAdapter(ListAdapter adapter) {
...此处省略部分代码...
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
...此处省略部分代码...
}
参考文献: