情景: 有两个分类,每个分类下的数据用listview显示,分类1需要显示头视图和尾视图,分类2不要显示头视图和尾视图 。两个分类可以来回切换。

实现的步骤: 1. addHeaderView 、 addFooterView,默认显示分类1的数据,setAdapter绑定 

2. 点击分类2时,先removeheaderview、removefooterview,然后setAdapter重新绑定数据

3. 点击分类1时,addHeaderView、addFooterView,然后setAdapter重新绑定数据

修改之前的代码:

   public void addHeaderFooter(){
if(!hasHead){
listview.addHeaderView(tv_head);
hasHead = true;
}
if(!hasFoot){
listview.addFooterView(tv_foot);
hasHead = false;
}
}
@Override
public void onClick(int position) {
Log.d(TAG, "position " + position + " is clicked!");
switch(position){
case 1:
//不需要header和footer
if(hasHead){
listview.removeHeaderView(tv_head);
hasHead = false;
}
if(hasFoot){
listview.removeFooterView(tv_foot);
hasFoot = false;
}
break;
default:
//其余分类都需要
addHeaderFooter();
break;
}

遇到的问题: 

步骤3中addHeaderView时报错:

解决办法:

add之前, setAdapter(null).

查看源码可知:

将adapter置null后,就不会报错了



这样改之后又遇到了一个问题:

步骤3中addFooterView时报错:

追踪源码可知:

此处getAdapter为null(之前调用了setAdapter(null)),所以nullpointer了

为什么会走到这一步呢,查看addFooterView的源码:

调用了mDataSetObserver.onChanged(),

而这个 mDataSetObserver 在哪里呢?见setAdapter源码:

原来,在步骤1中调用了setAdapter设置数据,所以这里的mDataSetObserver就存在了。

所以在setAdapter(null)之后,调用addFooterView时,由于mDataSetObserver依然存在,就会调用mDataSetObserver.onChanged()方法,从而调用getAdapter方法,返回null,再调用getcount时就nullpointer了。

解决办法: 我是在addFooterView之前又绑定了一次,setAdapter,给了一个空的数据源进去,只是确保adapter不为null。 这个方法有点投巧,没找到好的方法。



改正后的代码:

public void addHeaderFooter(){
listview.setAdapter(null);
if(!hasHead){
listview.addHeaderView(tv_head);
hasHead = true;
}
if(!hasFoot){
SimpleAdapter adapter = new SimpleAdapter(this, empty_list, R.layout.funtest_listview_item,
new String[]{ FuntestColumns.name,FuntestColumns.r_count,FuntestColumns.description},
new int[]{R.id.funtest_name, R.id.funtest_hot, R.id.funtest_description});
listview.setAdapter(adapter);
listview.addFooterView(tv_foot);
hasHead = false;
}
}
@Override
public void onClick(int position) {
Log.d(TAG, "position " + position + " is clicked!");
switch(position){
case 1:
//不需要header和footer
if(hasHead){
listview.removeHeaderView(tv_head);
hasHead = false;
}
if(hasFoot){
listview.removeFooterView(tv_foot);
hasFoot = false;
}
break;
default:
//其余分类都需要
addHeaderFooter();
break;
}

总结: 多次调用addHeaderView、addFooterView时

1. addHeaderView之前调用setAdapter(null)

2. addFooterView之前调用setAdapter(adapter); //adapter中传入空数据源

问题解决:listview多次调用addHeaderView和addFooterView的更多相关文章

  1. Android listview addHeaderView 和 addFooterView 详解

    addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 需要注意的是添加布局的时候应该添加从父容器开始添加 ...

  2. RecyclerView更通用——listView的onItemClick,onLongItemClick,addHeaderView,addFooterView

    一.点击事件 setOnItemClickListener,setOnItemLongClickListener RecyclerView中虽然没有提供上面这两个接口,但是给我们提供了另外一个接口:O ...

  3. ListView在列表的头部和底部添加布局——addHeaderView,addFooterView

    addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 以addHeaderView为例: View he ...

  4. android listview addHeaderView和addFooterView的注意事项

    1. item内如果有button等控件时,在监听listview的onitemclick事件时,焦点会被item内的button. imagebutton等控件抢走,从而导致在listview设置了 ...

  5. Android 关于ListView中adapter调用notifyDataSetChanged无效的原因

    话说这个问题已经困扰我很久了,一直找不到原因,我以为只要数据变了,调用adapter的notifyDataSetChanged就会更新列表,最近在做微博帐号管理这一块,想着动态更新列表,数据是变了,但 ...

  6. android ListView 多次调用 getView方法

    <ListView            android:layout_width="match_parent"            android:layout_heig ...

  7. Android开发之关于ListView中adapter调用notifyDataSetChanged无效的原因

    1.数据源没有更新,调用notifyDataSetChanged无效. 2.数据源更新了,但是它指向新的引用,调用notifyDataSetChanged无效. 3.数据源更新了,但是adpter没有 ...

  8. C# winfrom listview 多窗口调用

    Form1 private void button1_Click(object sender, EventArgs e) { Form f = new Form2(ref listView1); f. ...

  9. 【Android - 自定义View】之自定义可下拉刷新或上拉加载的ListView

    首先来介绍一下这个自定义View: (1)这个自定义View的名称叫做 RefreshableListView ,继承自ListView类: (2)在这个自定义View中,用户可以设置是否支持下拉刷新 ...

随机推荐

  1. js时间操作getTime(),ios移动端真机上返回显示NAN

    ios移动端,js时间操作getTime(),getFullYear()等返回显示NaN的解决办法及原因 在做移动端时间转化为时间戳时,遇到了一个问题,安卓手机上访问时,能拿到时间戳,从而正确转换时间 ...

  2. linux 详解

    一.日常使用命令/常用快捷键命令开关机命令        1.shutdown –h now:立刻进行关机 2.shutdown –r now:现在重新启动计算机 3.reboot:现在重新启动计算机 ...

  3. IntelliJ IDEA community 安装教程

    jetbrains官网下载 IntelliJ IDEA安装包 https://www.jetbrains.com/idea/download/#section=windows 此处选择社区版的zip文 ...

  4. 编写函数处理user_list,新方法

    写函数,完成以下功能: # 例如有: user_list=[ {"name": "alex","hobby":"抽烟"} ...

  5. Nginx是什么?

    Nginx是什么? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器.一直纳闷这个X是怎么来 ...

  6. [计蒜之道2019 复赛 A]外教 Michale 变身大熊猫

    [计蒜之道2019 复赛 A]外教 Michale 变身大熊猫 Online Judge:2019计蒜之道 复赛 A Label:LIS+线段树.树状数组+快速幂(模逆元) 题目描述 题解: pre. ...

  7. 微信小程序--导航跟随

    最近开发小程序的时候遇到这样一个需求:如图1 页面向下滚动到白色导航的位置时,白色导航固定到页面最上方:当页面向上滚动到白色导航时,白色导航恢复到原始位置:点击各个导航,平滑的跳到相应位置. 思路1: ...

  8. 巧用having

    mysql学习教程参考:https://www.w3school.com.cn/sql/index.asp where 与 having实例运用参考:https://www.2cto.com/data ...

  9. [转]C#接收邮件

    最近由于工作需要,接触到了邮件服务器.以前我用CF写过,感觉没有什么,我想用C#来实现会更简单,但是万万没想到C#没有提供邮件接收的方法,令我很不解.通过我在网上查找,发现了一个国外公司写好的接收邮件 ...

  10. flex 手册摘要

    个人学习 摘抄翻译 http://www.cs.princeton.edu/~appel/modern/c/software/flex/flex.html#SEC1 程序的格式 分成显示的三部分 由% ...