Listview:Cannot add header view to list -- setAdapter has already been called

错误提示

使用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;
          }
        ...此处省略部分代码...
    }

参考文献:

http://blog.csdn.net/androiddevelop/article/details/8474939

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值