listview数据刷新分析(三)
来源:互联网 发布:闪电分期go淘宝商铺 编辑:程序博客网 时间:2024/06/15 21:16
5.1,概念
当adapter中的数据更新时,会调用notifyDataSetChanged方法来刷新listview,这应该是典型的观察者模式,背后的原理是什么呢?
5.2,注册
注册流程图如下,
调用listview的setadapter方法时,开始注册, setAdapter方法部分源码如下,
mDataSetObserver = new AdapterDataSetObserver();mAdapter.registerDataSetObserver(mDataSetObserver);
AdapterDataSetObserver是AbsListView的内部类,定义如下,
class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver { @Override public void onChanged() { super.onChanged(); if (mFastScroll != null) { mFastScroll.onSectionsChanged(); } } @Override public void onInvalidated() { super.onInvalidated(); if (mFastScroll != null) { mFastScroll.onSectionsChanged(); } } }
其中,有2个回调方法, onChanged和onInvalidated,当数据库发生改变时,应该会回调onChanged方法。
BaseAdapter中的registerDataSetObserver方法如下,
public void registerDataSetObserver(DataSetObserver observer) { mDataSetObservable.registerObserver(observer); }
mDataSetObservable 是一个DataSetObservable对象,其父类Observable的registerObserver方法如下,
public void registerObserver(T observer) { if (observer == null) { throw new IllegalArgumentException("The observer is null."); } synchronized(mObservers) { if (mObservers.contains(observer)) { throw new IllegalStateException("Observer " + observer + " is already registered."); } mObservers.add(observer); } }
mObservers是一个ArrayList,存放所有注册的观察者,
protected final ArrayList<T> mObservers = new ArrayList<T>();
这里观察者模式使用的很巧妙,直接使用一个内部类。
5.3, notifyDataSetChanged
调用流程图如下,
BaseAdapter 的notifyDataSetChanged方法如下,
public void notifyDataSetChanged() { mDataSetObservable.notifyChanged(); //直接调用DataSetObservable的notifyChanged方法
public void notifyChanged() { synchronized(mObservers) { // since onChanged() is implemented by the app, it could do anything, including // removing itself from {@link mObservers} - and that could cause problems if // an iterator is used on the ArrayList {@link mObservers}. // to avoid such problems, just march thru the list in the reverse order. for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } }}
取出mObservers中所有元素,然后调用其onChanged方法,
最后Adapterview的AdapterDataSetObserver内部类的onChanged方法如下,
public 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(); // 重新绘制 }
requestLayout和invalidate方法的区别,
1, requestLayout会重新对view的布局进行测量,布局以及绘制;而invalidate只是对view进行重绘。
2,如果view只需重绘而不需测量等,使用invalidate会更高效。
0 0
- listview数据刷新分析(三)
- ListView中notifyDataSetChanged()刷新数据不更新原因分析
- ListView刷新数据方法
- Android ListView数据刷新
- ListView数据动态刷新
- Qt ListView 刷新数据
- android listview数据刷新
- ListView数据动态刷新
- listview刷新数据异常
- listview数据刷新异常
- ListView数据动态刷新
- Android ListView数据刷新
- 动态刷新listview数据
- Listview刷新数据
- listview数据局部刷新
- listview数据刷新问题
- listView下拉刷新加载数据
- listView下拉刷新加载数据
- R语言xgboost自定义目标函数
- 【JZOJ3839】Baby Step
- 2 Python 利用socket实现的服务端和客户端
- 找出符合以下条件的Troitsky数,将该数的首位数字移动到末位数字之后得到的数是原数的整数倍 例如:将142857的首位数字1移动到末位之后得到的数是428571,而428571=3*1
- hdu 5997 rausen loves cakes [启发式合并+树状数组/线段数]【杂类+数据结构】
- listview数据刷新分析(三)
- struct device *dev
- SDN关键技术
- Openstack入门过程
- 打包ZIP
- TCP/IP三次握手的详细过程
- MFC picture控件加载透明png图片
- ue4中动画通知的几种方式
- Codeforces_488C:Fight_the_Monster(暴力)