ListView想要添加headerview的话,就要通过addHeaderView这个方法,然后想要为ListView设置数据的话,就要调用setAdapter方法了。但是,在调用addHeaderView和setAdapter的顺序上,有时会爆出Java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.的异常。这是因为我们在addHeaderView之前调用了setAdapter。所以,在这里,建议setAdapter需要在addHeaderView和addfooterView之后调用。这样就安全了。下面,我们来看看源码吧。看看究竟是什么原因造成的。

Android-18(4.3)的addHeaderView源码:

public void addHeaderView(View v, Object data, boolean isSelectable) {  
        final FixedViewInfo info = new FixedViewInfo();  
        info.view = v;  
        info.data = data;  
        info.isSelectable = isSelectable;  
        mHeaderViewInfos.add(info);  
   
        // Wrap the adapter if it wasn't already wrapped.  
        if (mAdapter != null) {  
            if (!(mAdapter instanceof HeaderViewListAdapter)) {  
                mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);  
            }  
   
            // In the case of re-adding a header view, or adding one later on,  
            // we need to notify the observer.  
            if (mDataSetObserver != null) {  
                mDataSetObserver.onChanged();  
            }  
        }  
}  

Android-17(4.2)的addHeaderView的源码:

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.");  
        }  
   
        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();  
        }  
}  

  

  在上面,我们可以对比出代码中的处理的不同。在17版本中,只要adapter不为空的话,那就直接会抛出异常,而这个异常恰好就是我们文章开头说到的异常。在18版本中,如果adapter不为空的话,则会新建一个adapter,这个adapter会包含了headerview和footerview以及我们传进来的原来的adapter。这是在18版本以后做的一个处理。虽然有了处理,但是建议大家还是按照上面说的调用顺序来使用addHeaderView,addFooterView和setAdapter吧。

从源码上分析ListView的addHeaderView和setAdapter的调用顺序的更多相关文章

  1. 从源代码上分析ListView的addHeaderView和setAdapter的调用顺序

    ListView想要加入headerview的话,就要通过addHeaderView这种方法,然后想要为ListView设置数据的话,就要调用setAdapter方法了.可是,在调用addHeader ...

  2. 硬核干货:4W字从源码上分析JUC线程池ThreadPoolExecutor的实现原理

    前提 很早之前就打算看一次JUC线程池ThreadPoolExecutor的源码实现,由于近段时间比较忙,一直没有时间整理出源码分析的文章.之前在分析扩展线程池实现可回调的Future时候曾经提到并发 ...

  3. 【转】从源码来分析ListView

    原文:http://yanmingming.sinaapp.com/?p=1251 原文其实不叫这个名字,本文对于原文有一定的修改,觉得这个名字比较适合本篇. 一.ListView 的工作原理 Ada ...

  4. Android addHeaderView和setAdapter的调用顺序后报错

    在4.4之前的系统,setAdapter后再设置addHeaderView会爆 ListView想要添加headerview的话,就要通过addHeaderView这个方法,然后想要为ListView ...

  5. JUC同步器框架AbstractQueuedSynchronizer源码图文分析

    JUC同步器框架AbstractQueuedSynchronizer源码图文分析 前提 Doug Lea大神在编写JUC(java.util.concurrent)包的时候引入了java.util.c ...

  6. 自定义View系列教程02--onMeasure源码详尽分析

    深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...

  7. MapReduce的ReduceTask任务的运行源码级分析

    MapReduce的MapTask任务的运行源码级分析 这篇文章好不容易恢复了...谢天谢地...这篇文章讲了MapTask的执行流程.咱们这一节讲解ReduceTask的执行流程.ReduceTas ...

  8. MapReduce的MapTask任务的运行源码级分析

    TaskTracker任务初始化及启动task源码级分析 这篇文章中分析了任务的启动,每个task都会使用一个进程占用一个JVM来执行,org.apache.hadoop.mapred.Child方法 ...

  9. TaskTracker任务初始化及启动task源码级分析

    在监听器初始化Job.JobTracker相应TaskTracker心跳.调度器分配task源码级分析中我们分析的Tasktracker发送心跳的机制,这一节我们分析TaskTracker接受JobT ...

随机推荐

  1. 【Java并发编程】:并发新特性—信号量Semaphore

    在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步.当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定 ...

  2. 安装Elasticsearch5.0 部署Head插件

    部署5.0版本的ES 5.0版本的ES跟之前的版本最大的不同之处就是多了很多环境的校验,比如jdk,max-files等等. 设置内核参数 vi /etc/sysctl.conf # 增加下面的内容 ...

  3. Android Studio修改字体大小

    android studio提供的主题是不能修改字体和字体大小的,如果要修改大小就的另存一份自定义的主题了. 1.启动Android Studio,菜单"File"-"S ...

  4. 分区助手官网使用教程(专业版、绿色版和WinPE版)(图文详解)

    不多说,直接上干货! 详情见 http://www.disktool.cn/jiaocheng/index.html http://www.disktool.cn/jiaocheng/index2.h ...

  5. IDEA里运行程序时出现Failed to execute goal org.scala-tools:maven-scala-plugin:2.15.2:compile(default) on Project DataFusion:wrap:org.apache.commons...错误的解决办法(图文详解)

    不多说,直接上干货! 问题详情 比如我们习惯在IDEA里打包用mvn clean package 在Scala IDEA for eclipse里出现mvn clean compile assembl ...

  6. win7,8走网络打印机出现删除设备和打印机门未关闭的解决方法

    不多说,直接上干货! 用学校的内网连接, 即可. 右键,查看设备网页. 出现下面的情况: 多学学. 欢迎大家,加入我的微信公众号:大数据躺过的坑        人工智能躺过的坑       同时,大家 ...

  7. docker网络之macvlan

    macvlan接口类型简单说类似于子接口,但相比子接口来说,macvlan接口拥有自己独立的mac地址,因此使用macvlan接口可以允许更多的二层操作.macvlan有四种模式:VEPA,bridg ...

  8. 模型的偏差bias以及方差variance

    1. 模型的偏差以及方差: 模型的偏差:是一个相对来说简单的概念:训练出来的模型在训练集上的准确度. 模型的方差:模型是随机变量.设样本容量为n的训练集为随机变量的集合(X1, X2, ..., Xn ...

  9. asterisk与freepbx常用的命令

    asterisk 常用命令: 通过asterisk -r 连接我们的asterisk. 在CLI中常用的命令: sip show peers 显示所有的SIP peers(包括friends) sip ...

  10. vscode 常用配置

    { "workbench.iconTheme": "vscode-icons", "editor.tabSize": 2, "ed ...