转自:http://blog.csdn.net/whitley_gong/article/details/50562634

一、前言


       相信很多人都曾经被这个问题困扰,当然我也是这样过来的,原来以为只要数据变了,调用adapter的notifyDataSetChanged就会更新列表,然而结果却没有实现,其实是在一些细节上没有注意造成的,所以现在对这个问题进行下总结希望可以帮助到有需要的人。


二、原因分析


有以下三个原因:

1、数据源没有更新,调用notifyDataSetChanged无效。

2、数据源更新了,但是它指向新的引用,调用notifyDataSetChanged无效。

3、数据源更新了,但是adpter没有收到消息通知,无法动态更新列表。

一般来说,我们都是第二个原因造成的。


三、举例分析


分析了原因还是直接写个例子来说明,这样更加清楚。
正常情况:点击添加,然后点击更新界面。

关于ListView中adapter调用notifyDataSetChanged失效的原因总结

事件代码:
[java] view plain copy
  1. public void onClicked(View view) {  
  2.        switch (view.getId()) {  
  3.            case R.id.btn_add://添加  
  4.                for (int i = 0; i < 2; i++) {  
  5.                    People people = new People("女神" + i, imgs[2]);  
  6.                    peopleList.add(people);  
  7.                }  
  8.   
  9.                break;  
  10.            case R.id.btn_add2://添加失败  
  11.                peopleList = new ArrayList<>();  
  12.                for (int i = 0; i < 2; i++) {  
  13.                    People people = new People("女神" + i, imgs[3]);  
  14.                    peopleList.add(people);  
  15.                }  
  16.                // myAdapter = new MyAdapter(this, peopleList);  
  17.   
  18.                break;  
  19.            case R.id.btn_replace://通知更新  
  20.                peopleList = new ArrayList<>();  
  21.                for (int i = 0; i < 2; i++) {  
  22.                    People people = new People("女神" + i, imgs[4]);  
  23.                    peopleList.add(people);  
  24.                }  
  25.                myAdapter.setData(peopleList);  
  26.                break;  
  27.            case R.id.btn_notify://更新  
  28.                myAdapter.notifyDataSetChanged();  
  29.                break;  
  30.            default:  
  31.   
  32.                break;  
  33.        }  
  34.    }  

myAdapter = new MyAdapter(this, peopleList)
实例化MyAdapter,这里两个参数。点击添加后数据源peopleList添加了两个People对象,点击更新,实际就是调用notifyDataSetChanged(),listview正常更新,ok没有问题!

接着演示个失败的案例。
关于ListView中adapter调用notifyDataSetChanged失效的原因总结
      我已经拼命点了怎么就是没有效果,对比上面的代码,发现点击失败的case里多了一句话,
      peopleList = new ArrayList<>();
       难道就是这句造成的?没错,就是它,也就是上面的原因2。虽然数据源更新了,但是它指向新的引用,可是我们的Adapter绑定的还是原来数据源的引用,自然你调用更新,我们的Adapter认为是没有变化,所以失效。没事我们重新绑定下Adapter的数据源,打开上面注释的话,再来,可是结果你会发现这样也是不行的,因为虽然Adaper是更新了数据源,可是这个Adapter和原来的Adapter已经不一样了,listView却还是不知道这样的变化,所以调用也会无效。
正确的做法是现在Adaper写一个更新数据源的方法,这样就不会出现问题了。(上面点击通知更新的情况)
[java] view plain copy
  1. public void setData(List<People> newPeopleList){  
  2.        this.peopleList = newPeopleList;  
  3.    }  


四、总结


       上面说的这么多,不知道大家有没有懂,其实根本原因就是listview+adapter+数据源这三者的绑定,如果因为指向新的引用造成三者没有了原来的捆绑关系,自然调用notifyDataSetChanged()就会失效


相关文章: