notifyDataSetChanged和notifyDataSetInvalidated区别以及观察者模式的使用

看Observer和Observable的时候,爬了下Listview的源码,研究了下ANdroid中用到的观察者模式


两个方法

相同点

当改变Adapter数据后,调用两个方法都会刷新视图

不同点

notifyDataSetChanged会保存刷新前的状态,比如Listview滑动的位置;
notifyDataSetInvalidated会清空所有信息,重新布局,位置会到最上方;

源码

源码位于AdapterView中的内部类AdapterDataSetObserver (观察者)

class AdapterDataSetObserver extends DataSetObserver {private Parcelable mInstanceState = null;@Overridepublic void onChanged() {mDataChanged = true;mOldItemCount = mItemCount;mItemCount = getAdapter().getCount();// 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();}@Overridepublic void onInvalidated() {mDataChanged = true;if (AdapterView.this.getAdapter().hasStableIds()) {// Remember the current state for the case where our hosting activity is being// stopped and later restartedmInstanceState = AdapterView.this.onSaveInstanceState();}// Data is invalid so we should reset our statemOldItemCount = mItemCount;mItemCount = 0;mSelectedPosition = INVALID_POSITION;mSelectedRowId = INVALID_ROW_ID;mNextSelectedPosition = INVALID_POSITION;mNextSelectedRowId = INVALID_ROW_ID;mNeedSync = false;checkFocus();requestLayout();}public void clearSavedState() {mInstanceState = null;}}
源码说明
  • notifyDataSetChanged

    当调用notifyDataSetChanged,通过观察中会调用到onChanged,
    其中AdapterView.this.onRestoreInstanceState(mInstanceState);保存了当前Listview布局信息;
    最终调用父类 View 中`requestLayout()`重新布局;

  • 当调用notifyDataSetInvalidated , onInvalidated会被调用,布局信息被初始化,最终调用requestLayout,布局恢复初始状态。

使用场景

如果需要adapter丢弃用户操作后的信息,可以调用notifyDataSetInvalidated ,让listview初始化;反之则调用notifyDataSetChanged,让当前页面的位置,选中状态等信息保持不变;
当然最终使用场景可以分别调用两种方法实验。


观察者模式在Listview中的使用

Android 没有使用java提供的Observable ,而是使用Android源码中android.database.Observable<>

观察者模式的具体实现

  • 基类 Observable中 registerObserver unregisterObserver提供添加和删除观察者的方法;
  • 子类 DataSetObservable继承Observable,提供notifyChanged 通知mObserver.onChanged(),提供notifyInvalidated调用 mObserver.onInvalidated;
  • 观察者 DataSetObserver 中提供了 onChanged和onInvalidated两个未实现的方法;
  • Listview系列view的基类adapterView中提供了内部类AdapterDataSetObserver 继承DataSetObserver 实现了DataSetObserver的两个方法,用了操作ListView不同的状态;

具体实现

  • BaseAdapter中注册mDataSetObservable 被观察者,以及通知观察者
    DataSetObservable mDataSetObservable = new DataSetObservable();public void registerDataSetObserver(DataSetObserver observer) {mDataSetObservable.registerObserver(observer);}public void unregisterDataSetObserver(DataSetObserver observer) {mDataSetObservable.unregisterObserver(observer);}public void unregisterDataSetObserver(DataSetObserver observer) {mDataSetObservable.unregisterObserver(observer);}public void notifyDataSetChanged() {mDataSetObservable.notifyChanged();}
  • AbsListView中注册和解绑
    @Overrideprotected void onAttachedToWindow() {mDataSetObserver = new AdapterDataSetObserver();mAdapter.registerDataSetObserver(mDataSetObserver);}@Overrideprotected void onDetachedFromWindow() {mAdapter.unregisterDataSetObserver(mDataSetObserver);mDataSetObserver = null;}
  • 在加上文章最上面的源码,一套流程over

源码爬的很开心,pompip原创

notifyDataSetChanged和notifyDataSetInvalidated区别以及观察者模式的使用相关推荐

  1. adapter.notify()、notifyAll()、notifyDataSetChanged ()、notifyDataSetInvalidated ()的区别

    adapter.notify().notifyAll().notifyDataSetChanged ().notifyDataSetInvalidated ()的区别 notify()和notifyA ...

  2. notifyDataSetInvalidated()和notifyDataSetChanged()有什么区别? (转载)

    notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容. public void notifyDataSetChan ...

  3. Android中notifyDataSetInvalidated()和notifyDataSetChanged()有什么区别

      看下源码中对于这两个方法   public void notifyDataSetChanged () 该方法内部实现了在每个观察者上面调用onChanged事件.每当发现数据集有改变的情况,或者读 ...

  4. notifyDataSetInvalidated()和notifyDataSetChanged()有什么区别

    notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容. public void notifyDataSetChan ...

  5. notifyDataSetInvalidated()和notifyDataSetChanged()有什么区别?

    notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容. public void notifyDataSetChan ...

  6. Android中notifyDataSetInvalidated()和notifyDataSetChanged()

    首先看一下notifyDataSetChanged与notifyDataSetInvalidated的区别: 我们打开官方的源码: /*** Notifies the attached observe ...

  7. Java观察者模式以及与订阅发布者模式区别

    设计模式复习,代码是最好的说明. 定义:观察者模式定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新,属于行为类模式. 注意:观察者模式和发布订阅模式 ...

  8. JS观察者模式和发布订阅模式的区别

    观察者模式: 观察者观察被观察者,当被观察者发生被观察的行为时,触发观察者里面的事件. document.querySelector('#btn').addEventListener('click', ...

  9. Android 开发中的观察者模式应用实例

    前言 最近在遇到了 Android 的开发中常用到的设计模式之观察者模式,观察者模式,所谓的模式就是一种设计思想,可以按照某种模式,写出更合理,简单,有效的代码.可以用在 Android 开发中,也可 ...

最新文章

  1. redis3.0 java spring_spring整合redis以及使用RedisTemplate的方法
  2. 单例设计模式-容器单例
  3. 官网下载mysql实例数据库
  4. 【渝粤教育】 国家开放大学2020年春季 2542行政组织学 参考试题
  5. java 提交的内存_Java使用内存映射实现大文件的上传
  6. 做开源界的MATLAB,PyMiner 需要更多热爱开源的你加入
  7. 防火墙配置文件iptables详解
  8. sans webcast
  9. Eclipse如何使用Git完成代码比对并提交操作
  10. 树莓派系统备份与还原
  11. 奇点云数据中台技术汇(一) | DataSimba——企业级一站式大数据智能服务平台
  12. python程序内存限制
  13. Intellij IDEA 在win10 中输入法的输出框不跟随
  14. 音响功放用R型变压器有什么好处?
  15. 暑假实训-3_Oracle数据库-3_单行函数
  16. 星系炸弹 在X星系的广袤空间中漂浮着许多X星人造“炸弹”,用来作为宇宙中的路标。 每个炸弹都可以设定多少天之后爆炸。 比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16
  17. JSP javaweb餐厅点餐系统源码(点餐系统)点餐系统网上订餐系统在线订餐系统
  18. 泛函,变分,欧拉-拉格朗日方程
  19. [ivo UI] 适合初学者的HTML5 UI组件库
  20. 非常规角度的PCB数据如何实现快速拼版

热门文章

  1. 人工智能数学基础---定积分8:无穷限反常积分审敛法
  2. 斯诺克 装备、比赛规则
  3. 龙芯PMON(2K1000)启动流程(三、C语言部分③)
  4. Android运行环境Dalvik模式和ART模式的区别
  5. 【BZOJ3217】ALOEXT-暴力重构线段树-替罪羊树-Trie树-树套树-10k大代码(+数据生成器)...
  6. a+=b和a=a+b区别
  7. 【吴刚】淘宝天猫网站设计初级入门标准视频教程-吴刚-专题视频课程
  8. Android Launcher3分析——开篇
  9. 盘点常用的站长SEO工具
  10. ADO Error: 0x80040E14