学过Android开发的人都知道,ListView控件在开发中经常遇到,并且ListView通常结合Adapter适配器来进行数据显示和数据更新操作。姑且假设数据存储在名为dataList的成员变量中。数据操作无非是增加数据、删除数据这两种主要的操作,而当数据有所变化时,为了及时向用户提供更新后的数据,我们知道需要在数据更新后调用适配器的notifyDataSetChanged()方法,来显示更新后的数据。殊不知,该方法并非百试不爽,在此我们便来讨论下具体的原因,其实本质是关注内存的分配情况。

先来看几段代码。

代码段1(某Activity中):

private List> dataList;

private ListView listView;

private ListAdapter adapter;

listView = findViewById(R.id.mancard);

adapter = new ListAdapter(this, dataList);

listView.setAdapter(adapter);

上述代码是把Adapter适配器和ListView控件进行绑定。

代码段2(ListAdapter中的部分代码):

public class ListAdapter extends BaseAdapter{

private Context context;

private List list;

ListAdapter(Context context, List list){

this.context = context;

this.list = list;

}

@Override

public Object getItem(int position) {

return list.get(position);

}

上述代码是通过上下文环境和数据列表来构造适配器,并且重写其getItem()方法。在此需要明白的是list成员变量是适配器中的私有变量,getItem()方法是当数据显示在ListView时会回调的方法,或者说当显示数据或数据发生改变重写加载数据时会回调这个方法(当然还会调用getView()方法,此时不再赘述)。

代码段3~6模拟数据改变:

代码段3:

dataList.remove(1);

adapter.notifyDataSetChanged();

代码段4:

Map vivian = new HashMap();

vivian.put("sex", "girl");

vivian.put("nick", "vivian");

vivian.put("content", "阳光魅力大方无极限");

dataList.add(vivian);

adapter.notifyDataSetChanged();

代码段5:

dataList = getData();

adapter.notifyDataSetChanged();

private List getData(){

List data = new ArrayList();

Map vivian = new HashMap();

vivian.put("sex", "girl");

vivian.put("nick", "vivian");

vivian.put("content", "阳光魅力大方无极限");

data.add(vivian);

Map Mryang = new HashMap();

Mryang.put("sex", "boy");

Mryang.put("nick", "杨阳洋");

Mryang.put("content", "成熟稳重高富帅");

data.add(Mryang);

return data;

}

代码段6:

dataList.clear();

dataList.addAll(getData());

adapter.notifyDataSetChanged();

getData()方法同代码段5(略)

以上几种情况模拟了常用的更新数据的方法,在这几种情况种代码段5不能实现数据的更新操作,代码段3、4、6可以实现数据更新操作。为什么代码段3、4、6可以更新,原因大家都明白,是因为数据发生了变化,因此当调用adapter.notifyDataSetChanged()方法时就会把更新后的数据显示出来。

代码段5的数据也发生了变化,为什么不能实现数据更新呢?

当构造Adapter适配器,数据列表dataList传递过去时,是把dataList指向的地址副本作为参数传递给了adapter中的list成员变量了,因此dataList指向的内存区域和adapter中list指向的内存区域是同一块内存区域,代码段3和代码段4对数据的添加、删除操作是在当前区域内进行的,dataList中数据的变化直接影响了adapter中list的数据的变化,因此adapter中的list能够敏感的发现数据发生变化。

代码段3、4简易模型

代码段5中,对dataList的内存指向做了修改,但是该指向并没有通知到adapter中的list,也就是说list指向没有发生变化,还是指向原来修改前的内存区域,因此dataList的改变并不能引起list的改变,本质上来说list没有发现数据有变化,所以当调用adapter.notifyDataSetChanged()方法时,数据没有更新。而在代码段6中,首先移除dataList中的数据,那么adapter中的list自然能够及时发现数据发生了变化,从而重新从dataList中得到改变后的数据信息,因此当调用adapter.notifyDataSetChanged()方法时能够发生数据的更新。

代码段5简易模型

代码段6简易模型

因此当我们想要更换ListView中的所有数据时,应该采用代码段6的方式,先将数据移除,再重新添加数据或更换新的内存区域指向。

android notifydatasetchanged 刷新错误,Android中适配器的notifyDataSetChanged()为何有时不刷新...相关推荐

  1. Android记录15--关于ListView中adapter调用notifyDataSetChanged无效的原因

    Android记录15--关于ListView中adapter调用notifyDataSetChanged无效的原因 2014年1月16日 开发记录 话说这个问题已经困扰我很久了,一直找不到原因,我以 ...

  2. android notifydatasetchanged 刷新错误,android – notifyDataSetChanged()不刷新可扩展列表视图...

    我正在使用Expandable ListView,其中的数据通过Sqlite数据库填充.我已经选择从ExpandableListView中删除一个组,它实际上删除了数据库中的相应行.但是活动不会刷新, ...

  3. Android布局文件错误,android 布局文件常见错误

    1.'Missing contentDescription attribute on image' in XML 原因:缺少图片描述,在 ADT 16 开始会抛出这个警告,确保开发者为图片添加内容描述 ...

  4. android autolink识别错误,android - autolink窃取ontouch事件,从而反馈触摸列表视图行无效 - 堆栈内存溢出...

    我有一个listview . 并且行布局中包含很少的布局. 在行布局中,我有一个TextView ,我想在其上启用自动链接当我启用自动链接时,链接工作正常但我们点击列表行时得到的反馈不再有效. 在行布 ...

  5. android notifydatasetchanged 刷新错误,Android 调用notifyDataSetChanged方法失败解决办法

    Android 调用notifyDataSetChanged方法失败解决办法 如果使用ListView.GridView等进行数据展示,当绑定的数据有了更新的时候,需要实时刷新ListView,即调用 ...

  6. android r文件错误,Android R文件丢失异常原因汇总

    Console报错:R.java was modified manually! Reverting to generated version! 引言: R文件丢失异常在java开发中是个比较常见的异常 ...

  7. android模块编译错误,android studio编译出错:Android resource linking failed

    问题描述 今天在Android studio通过模拟器运行app的时候,出现了以下错误: Android resource linking failed AAPT: D:\developer\andr ...

  8. android ndk 段错误,android crash之段错误原因及分析方法

    在解决app/frameworks客户问题的过程中经常碰到段错误的问题,在Aplog中搜索fatal关键字会碰到类似F/libc    ( 6721): Fatal signal 11 (SIGSEG ...

  9. android内存溢出错误,Android Studio 生成 JavaDoc 空指针异常|文档编码出错|内存溢出...

    一般使用Android Studio生成 JavaDoc会有三个问题: 1.空指针异常 Tools --> Generate JavaDoc -->打开对话框活,在"Other ...

最新文章

  1. iOS日常工作之常用宏定义大全
  2. IntelliJ IDEA 、 Android Stadio 不显示Version Contro窗口
  3. 为什么视频压缩如此重要
  4. 通过Windows Visual Studio远程调试WSL2中的.NET Core Linux应用程序
  5. Win7,Win8下多实例运行Excel2010
  6. CSS 元素的绝对定位 position: absolute 和 position: fixed
  7. 用户名和密码都正确,无法直接登陆虚拟机上的linux
  8. [c#]获取exchange中的图片
  9. java 单链表是否有环_数据结构与算法随笔之链表-链表是否有环(二)
  10. nginx+tocmat ip_hash做负载均衡时,一台tomcat宕机时没有转发问题
  11. 【今晚群分享预告】 58集团监控系统实践
  12. IDL多进程批处理遥感数据
  13. 会让你变得与众不同的22个技巧
  14. 5款好用的bi报表工具
  15. 司凤为璇玑抗鸿蒙熔炉,琉璃:结局最惨的是司凤和若玉?而是让人心疼的他,他死的太可惜...
  16. MySQL - 索引的数据结构
  17. AI切片工具是如何使用的
  18. 多线程 - 三种实现
  19. 数据结构(九)——外部排序之外排序
  20. 2020最新最全的全国省市区五级四级三级地址数据库sql下载,excel下载

热门文章

  1. 【图片新闻】美国海军新型核弹头W-76-2将于2019年底交付
  2. Linux 内核数据结构解析--无锁链表
  3. SW问题:soildworks2021拉伸凸台指令拉伸后看不见实体如何解决
  4. ETL的介绍与使用ETL工具之间的区别
  5. oracle查询父子节点,oracle 父子节点 查询
  6. Android实战简单新闻主界面设计
  7. 太强了!GitHub开源了1000本技术类的电子书,直接刷爆朋友圈!
  8. 【Python自动化办公】实现excel表中的数据批量导入到word指定位置(表格形式和下滑线形式)
  9. java日程管理源代码_Java日程管理——万年行事历源代码
  10. 友盟分享插件 for Flutter