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

一、前言


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


二、原因分析


有以下三个原因:

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

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

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

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


三、举例分析


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


事件代码:
 public void onClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_add://添加
                for (int i = 0; i < 2; i++) {
                    People people = new People("女神" + i, imgs[2]);
                    peopleList.add(people);
                }

                break;
            case R.id.btn_add2://添加失败
                peopleList = new ArrayList<>();
                for (int i = 0; i < 2; i++) {
                    People people = new People("女神" + i, imgs[3]);
                    peopleList.add(people);
                }
                // myAdapter = new MyAdapter(this, peopleList);

                break;
            case R.id.btn_replace://通知更新
                peopleList = new ArrayList<>();
                for (int i = 0; i < 2; i++) {
                    People people = new People("女神" + i, imgs[4]);
                    peopleList.add(people);
                }
                myAdapter.setData(peopleList);
                break;
            case R.id.btn_notify://更新
                myAdapter.notifyDataSetChanged();
                break;
            default:

                break;
        }
    }

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

接着演示个失败的案例。

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


四、总结


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


源码下载



  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值