Override ListView getAdapter造成的后果
近期工作中,发现了一个bug,是和ListView Adapter有关的。产生了FC,描写叙述信息大约是
"The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(xxx) with Adapter(HeaderViewListAdapter)]"
它的大意是,Adapter内的数据发生了变化,可是UI却没有更新,您是否忘记调用了notifyDataSetChanged?
这实际上是一个很有误导的信息。普通情况下,我们不会忘记调用该函数的。可是假设我们不小心,从listview继承一个新的类,并override它的getAdapter方法,就可能会出问题了。
ListView是支持HeaderView和footerView的,即在listview的最初和最末尾的位置加入�一些特殊的view。它的实现方法,就是通过一个HeaderViewListAdapter。
HeaderViewListAdapter会包装一个Adapter,这个是由用户自己设置的。ListView中相应的代码是
@Override
public void setAdapter(ListAdapter adapter) {
if (mAdapter != null && mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
} resetList();
mRecycler.clear(); if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}
ListView的getAdapter返回的是mAdapter,就可以能是一个HeaderViewListAdapter.
假设override getAdapter,并返回HeaderViewListAdapter内部包装的Adapter,就会出问题。也就是上面提到的FC.
这样的问题是怎么出现呢?
首先,这个异常抛出的位置,是在函数layoutChildren中,抛出的条件是mItemCount != mAdapter.getCount(),代码例如以下:
else if (mItemCount != mAdapter.getCount()) {
throw new IllegalStateException("The content of the adapter has changed but "
+ "ListView did not receive a notification. Make sure the content of "
+ "your adapter is not modified from a background thread, but only from "
+ "the UI thread. Make sure your adapter calls notifyDataSetChanged() "
+ "when its content changes. [in ListView(" + getId() + ", " + getClass()
+ ") with Adapter(" + mAdapter.getClass() + ")]");
}
那么mItemCount的值是在哪里赋值呢?mItemCount不是ListView的成员,而是ListView的超超类:AdapterView的成员,这个值也是在DataObserver.onChanged中设置的,您可參考AdapterView的源代码:
class AdapterDataSetObserver extends DataSetObserver { private Parcelable mInstanceState = null; @Override
public void onChanged() {
mDataChanged = true;
mOldItemCount = mItemCount;
mItemCount = getAdapter().getCount(); //这里!注意使用方法getAdapter() // Detect the case where a cursor that was previously invalidated has
// been repopulated with new data.
if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
&& mOldItemCount == 0 && mItemCount > 0) {
AdapterView.this.onRestoreInstanceState(mInstanceState);
mInstanceState = null;
} else {
rememberSyncState();
}
checkFocus();
requestLayout();
}
假设 getAdapter() != mAdapter就会发生故障:getAdatper返回的是mAdapter(即HeaderListViewAdapter),那么,mAdapter.getCount() == getAdapter().getCount() + header view count + footer view count.
出现上面的问题就在所难免了。
Override ListView getAdapter造成的后果的更多相关文章
- 关于ScrollView嵌套ListView问题
Android开发之ScrollView中嵌套ListView的解决方案 原文:http://blog.csdn.net/minimicall/article/details/40983331 ...
- ScrollView中嵌套GridView,ListView只显示一行的解决办法
转载:http://blog.csdn.net/luohai859/article/details/39347583 关于为什么只显示一行,个人理解是:如果单独使用GridView和ListView, ...
- 双击导航栏自动滑动ListView到顶部
有些app都实现了双击导航栏让页面的list自动滑动到顶部的feature. 先实现一个继承于OnTouchListener的监听多次点击事件的监听器,通过callback把连续点击的次数返回给客户代 ...
- 安卓中級教程(4):ScrollView與ListView之間的高度問題
在scrollView中加插ListView是一個大難題.其中一個難題是Listview的高度難以計算,輸出效果往往強差人意,就讓我們看看當中的問題 . <LinearLayout xmlns: ...
- Android listview addHeaderView 和 addFooterView 详解
addHeaderView()方法:主要是向listView的头部添加布局addFooterView()方法:主要是向listView的底部添加布局 需要注意的是添加布局的时候应该添加从父容器开始添加 ...
- ScrollView与ListView冲突解决
正 常来说,在ScrollView添加一个ListView后在真机上只会显示ListView的一行多一点,我也不理解为什么会这样,后来我把 ListView的layout_height改成400dip ...
- 四种方案解决ScrollView嵌套ListView问题(转)
以下文章转自@安卓泡面 在工作中,曾多次碰到ScrollView嵌套ListView的问题,网上的解决方法有很多种,但是杂而不全.我试过很多种方法,它们各有利弊. 在这里我将会从使用ScrollVie ...
- 解决ScrollView嵌到listView冲突问题
方法一: 把下面的方法放在绑定适配器操作的下面就行. /** * 重新计算ListView的高度,解决ScrollView和ListView两个View都有滚动的效果,在嵌套使用时起冲突的问题 * @ ...
- ListView和ScrollView冲突
当ListView放在ScrollView中的时候,无论你设置高度为 match_parent(填充父窗体)和wrap_content(包裹内容)都只显示一行,这是你把ListView放在Linear ...
随机推荐
- Codeforces Round #230 (Div. 2) C Blocked Points
题目链接 题意 : 给你一个半径为n的圆,圆里边还有圆上都有很多整点,让你找出与圆外的任意一个整点距离等于1的点. 思路 :这个题可以用枚举,画个图就发现了,比如说先数第一象限的,往下往右找,还可以找 ...
- linux登录后出现_bash-4.1#终端提示符异常
如果使用root用户登录出现上述提示,则需要需要重建 /root .bash_profile文件: 1. vi /root .bash_profile 2. 输入如下内容 # .bashrc # Us ...
- HDU - 3594 Cactus
这是一个有向仙人掌的题目,要求判定给定的图是不是强连通图,而且每一条边只能出现在一个环中,这里有一个介绍有向仙人掌的文档:http://files.cnblogs.com/ambition/cactu ...
- Tomcat 6.0下配置HTTPS
最近项目需要使用到https,所以回顾整理了一下,其实在tomcat的文档中已经有了详细描述,我们启动Tomcat后,可以在docs文档中找到 地址如下:http://localhost:8080/d ...
- Android include和merge标签的使用
在Android布局文件中,某些时候使用include标签会很多的好处1,对于稍微有点复杂的布局界面,将所有布局代码都写在一个xml文件中,界面会显得很冗余,可读性很差,这时可以分开使用include ...
- 关于方程x^2+y^2=p (p为素数)的解问题
问题描述:对于方程,其中为素数,x,y为整数,且,输出符合条件的x,y. 分析:对于本方程,我们通过费马平方和定理知道,只有奇素数p满足这个条件时才有解. 那么当此方程有解时,解有几个呢?很明显不可能 ...
- 【原创】FPGA开发手记(二) VGA接口
以下内容均以Xilinx的Nexys3作为开发板 1.VGA接口介绍 首先,先看电路图(3*5为例): 标准VGA一共15个接口,但是实际应用的接口信号只用五个:HSYNC,行同步信号:VSYNC,场 ...
- 【HDOJ】1171 Big Event in HDU
母函数,先要算搞清楚组合数可能的最大值.非常大.N种设备的最大VAL*最大数量. #include <stdio.h> #include <string.h> #define ...
- javascript点击图片放大的功能(原生)
使用的图片: 1.jpg <!doctype html> <html lang="en"> <head> <meta charset=&q ...
- web.xml配置详解之欢迎页面和错误页面
<!-- 应用的欢迎页面 采用list的方式罗列欢迎页面, 系统会从第一个找到最后一个,找到了文件就不继续往下找了.优先显示前边的. --> <welcome-file-list& ...