问题解决:listview多次调用addHeaderView和addFooterView
情景: 有两个分类,每个分类下的数据用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的更多相关文章
- Android listview addHeaderView 和 addFooterView 详解
addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 需要注意的是添加布局的时候应该添加从父容器开始添加 ...
- RecyclerView更通用——listView的onItemClick,onLongItemClick,addHeaderView,addFooterView
一.点击事件 setOnItemClickListener,setOnItemLongClickListener RecyclerView中虽然没有提供上面这两个接口,但是给我们提供了另外一个接口:O ...
- ListView在列表的头部和底部添加布局——addHeaderView,addFooterView
addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 以addHeaderView为例: View he ...
- android listview addHeaderView和addFooterView的注意事项
1. item内如果有button等控件时,在监听listview的onitemclick事件时,焦点会被item内的button. imagebutton等控件抢走,从而导致在listview设置了 ...
- Android 关于ListView中adapter调用notifyDataSetChanged无效的原因
话说这个问题已经困扰我很久了,一直找不到原因,我以为只要数据变了,调用adapter的notifyDataSetChanged就会更新列表,最近在做微博帐号管理这一块,想着动态更新列表,数据是变了,但 ...
- android ListView 多次调用 getView方法
<ListView android:layout_width="match_parent" android:layout_heig ...
- Android开发之关于ListView中adapter调用notifyDataSetChanged无效的原因
1.数据源没有更新,调用notifyDataSetChanged无效. 2.数据源更新了,但是它指向新的引用,调用notifyDataSetChanged无效. 3.数据源更新了,但是adpter没有 ...
- C# winfrom listview 多窗口调用
Form1 private void button1_Click(object sender, EventArgs e) { Form f = new Form2(ref listView1); f. ...
- 【Android - 自定义View】之自定义可下拉刷新或上拉加载的ListView
首先来介绍一下这个自定义View: (1)这个自定义View的名称叫做 RefreshableListView ,继承自ListView类: (2)在这个自定义View中,用户可以设置是否支持下拉刷新 ...
随机推荐
- python数据类型,数据结构
数据类型:int,bool 数据结构:dict,list,tuple,set,str
- GitHub:如何构建一个股票市场知识图谱?(附代码&链接)
来源:专知 本文约 600007 董事⻓/董事 高燕 女 60 600007 执⾏董事 刘永政 男 50 600008 董事⻓/董事 ··· ··· ··· ··· ··· 注:建议表头最好用相应的英 ...
- Mac下使用Pecl安装PHP的Swoole扩展实践
一.背景 前段时间把Mac系统重装了,PHP的一些扩展都没了,昨天需要调试一个swoole开发的项目,发现命令行中的PHP是系统自带的,如果安装swoole扩展很不方便:需要自己手动去下载swoole ...
- 01-从这里开始js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 手机端META详细解释
一.天猫 <title>天猫触屏版</title> <meta content="text/html; charset=utf-8" http-equ ...
- 怎么对C++枚举(不是类)里面的东西进行随机
把枚举里面的东西取到一个数组如: enum 枚举类型 a[]={ 枚举元素 }; 变成了一个数组,然后把随机结果当成枚举数组的索引,就可以得到随机的枚举元素了.
- 关于bind
1, 目的 使程序可以感知到事件 2, 格式 widget.bind(event, handler) 3, handler注意事项 在这里, handler作为一个函数, 是需要一个event对象作为 ...
- 【HTML5】如何处理HTML5新标签的浏览器兼容版问题
HTML5规范毕竟是刚刚才定义完成的规范,还有一些浏览器并不能支持其中的新标签和新属性,尤其是IE8及以下版本浏览器.以下介绍一些在页面中使用HTML5新标签的实践方法,目的是让HTML5中的新标签在 ...
- Make the Most (Hackerrank Codeagon)
题目链接 Problem Statement Codenation is sending N of its employees to a High Profile Business Conferenc ...
- PAT甲级——A1031 Hello World for U
Given any string of N (≥) characters, you are asked to form the characters into the shape of U. For ...