ListView setAdapter has already been called 异常



一  遇到问题
ListView HeaderView使用过程中遇到的问题
1. 必须在setAdapter之前执行addHeaderView方法,否则会出现以下异常
java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.




二 分析源码查找原因
先来看问题1,查看下ListView.addHeaderView()源码分析原因
    public void addHeaderView(View v, Object data, boolean isSelectable) {
    
        // 只要mAdapter不为空就抛出此异常
        if (mAdapter != null && ! (mAdapter instanceof HeaderViewListAdapter)) {
            throw new IllegalStateException(
                    "Cannot add header view to list -- setAdapter has already been called.");
        }
		
        ......
    }


再分析下问题2,查看ListView.setAdapter()源码分析原因
    public void setAdapter(ListAdapter adapter) {

        .....

        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }
        
        .....
    }



原来使用了新的adapter



三 为什么HeaderView需要包装一个HeaderViewListAdapter?
     为什么addHeaderView时adapter必须为空
1. 先来看下ListView的继承体系
ListView -> AbsListView -> AdapterView -> ViewGroup

2. ListView继承自ViewGroup,如果需要添加视图只能通过ViewGroup.addView()添加,而在AdapterView.addView中可以看到此方法已经不让使用
    public void addView(View child) {
        throw new UnsupportedOperationException("addView(View) is not supported in AdapterView");
    }


3. 只能通过adapter的getview处理添加view,ListView内部是如何添加View?以下是方法调用堆栈
AbsListView.onTouchEvent -> 
AbsListView.scrollIfNeeded -> 
AbsListView.trackMotionScroll  -> 
AbsListView.fillGap -> 
ListView.fillDown/fillUp/fillFromMiddle -> 
ListView.makeAndAddView -> 
ListView.setupChild -> 
ListView.addViewInLayout



也可以在第一个item的布局中添加,但是这种方式会对ListView造成影响









2013-04-22   删除position引出的问题,拆分出一个独立的文章之前放到一起有点乱


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值