安卓notifyDataSetChanged无效 解决方法

来源:互联网 发布:有淘宝开店条件 编辑:程序博客网 时间:2024/06/05 17:27

        安卓项目中总是会使用到listview,不可避免地需要自定义adapter类。当listview中的数据需要刷新的时候,有着两种方法,第一种重新setAdapter相当于重新设置来数据源,但是存在问题的是会导致界面闪烁,因为数据均是重新加载一次,不适合于频繁地数据更新使用。第二种方法使用notifyDataSetChanged进行数据刷新,它对于发生变化的数据进行加载,保留原来部分位置信息,呈现效果只刷新了部分listview,适合于频繁数据刷新。

        从源码可以看出adapter类中使用了观察者模式,在setadapter方法中注册了一个AdapterDataSetObserver的观察者对象,adapter作为被观察者,当其数据源发生变化时则遍历自身的观察者集合,通知每一个观察者做出数据源发生变化后相应的onChanged方法。 

        关于setAdapter和notifyDataSetChange的区别,其实两者都对整个listview进行了重绘,不同地是notifyDataSetChanged保留了原有的位置和数据信息而setAdapter清空信息回到初始状态进行重新加载。

        notifyDataSetChanged刷新无效时一个常见的问题,导致问题的原因是notifyDataSetChanged的机制的问题。 当调用 notifyDataSetChanged方法时,adapter会检查数据源数据是否发生变化,发生变化则调用更新。很多时候,当出现以下写法的时候:

queryResList=new ArrayList<PingMessageBean>();//初始创建数据源  指向于堆上堆一个ArrayList对象queryResList = pingMsgTable.queryAll();//重新指向另外一个对象

        前面是创建的一个查询数据表返回的arrayList对象,它时存在于堆中的,而queryResList引用变量时存在于栈上,执行赋值语句后queryResList指向了一个新的对象,这时notifyDataSetChanged方法执行的时候,发现数据源都已经发生了变化就不知道和原数据源的差别在哪所以便不执行更新操作导致更新无效。

        发现原因后很容易找到解决方法,第一种解决方法,清空原有的queryResList后重新遍历加入新的结果集合中的元素即可,这样时基于原有数据源进行的修改。使用clear和addAll方法即可,再次不赘述。

        第二种,可以写一个方法在adapter中刷新数据源达到目的,代码如下:

public void setmList(List<PingMessageBean> mList) {        this.mList = mList;    }//写在自定义adapter类中
        当数据发生改变时,调用如下:

queryResList = pingMsgTable.queryAll();//获取数据pingStoredGridViewAdapter.setmList(queryResList);//设置数据源pingStoredGridViewAdapter.notifyDataSetChanged();
        如果重新构造adapter构造参数中重新载入list集合则相当于重新创建adapter,调用notifyDataSetChanged无效且无意义。让adapter自己更新数据源则可实现。

        个人理解,如有错误欢迎指正。

        特记下,以备后日回顾。

阅读全文
1 0
原创粉丝点击