最近由于遇到将内容分部绑定到ListView里的需求,追踪源码之后对ListView和Adapter有了点肤浅的认识,在此与大家分享。

这里用到了观察者模式,在ListView的setAdapter里注册一个AdapterDataSetObserver观察者。

  1. public void setAdapter(ListAdapter adapter) {
  2. ........
  3. mDataSetObserver = new AdapterDataSetObserver();//AdapterDataSetObserver是ListView的基类AdapterView的内部类
  4. mAdapter.registerDataSetObserver(mDataSetObserver);//注册一个观察者
  5. .........
  6. requestLayout();//更新视图
  7. }

ListAdapter是一接口,BaseAdapter继承了它

  1. public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
  2. private final DataSetObservable mDataSetObservable = new DataSetObservable();
  3. public boolean hasStableIds() {
  4. return false;
  5. }
  6. public void registerDataSetObserver(DataSetObserver observer) {
  7. mDataSetObservable.registerObserver(observer);
  8. }
  9. public void unregisterDataSetObserver(DataSetObserver observer) {
  10. mDataSetObservable.unregisterObserver(observer);
  11. }
  12. /**
  13. * Notifies the attached observers that the underlying data has been changed
  14. * and any View reflecting the data set should refresh itself.
  15. */
  16. public void notifyDataSetChanged() {
  17. mDataSetObservable.notifyChanged();
  18. }
  19. /**
  20. * Notifies the attached observers that the underlying data is no longer valid
  21. * or available. Once invoked this adapter is no longer valid and should
  22. * not report further data set changes.
  23. */
  24. public void notifyDataSetInvalidated() {
  25. mDataSetObservable.notifyInvalidated();
  26. }
  27. public boolean areAllItemsEnabled() {
  28. return true;
  29. }
  30. public boolean isEnabled(int position) {
  31. return true;
  32. }
  33. public View getDropDownView(int position, View convertView, ViewGroup parent) {
  34. return getView(position, convertView, parent);
  35. }
  36. public int getItemViewType(int position) {
  37. return 0;
  38. }
  39. public int getViewTypeCount() {
  40. return 1;
  41. }
  42. public boolean isEmpty() {
  43. return getCount() == 0;
  44. }
  45. }

DataSetObservable定义如下:

  1. public class DataSetObservable extends Observable<DataSetObserver> {
  2. public void notifyChanged() {//通知每个观察者数据已变化
  3. synchronized(mObservers) {
  4. for (DataSetObserver observer : mObservers) {
  5. observer.onChanged();
  6. }
  7. }
  8. }
  9. public void notifyInvalidated() {
  10. synchronized (mObservers) {
  11. for (DataSetObserver observer : mObservers) {
  12. observer.onInvalidated();
  13. }
  14. }
  15. }
  16. }

ListView里注册的观察者是AdapterDataSetObserver对象,其定义如下:

  1. class AdapterDataSetObserver extends DataSetObserver {
  2. private Parcelable mInstanceState = null;
  3. @Override
  4. public void onChanged() {
  5. mDataChanged = true;
  6. mOldItemCount = mItemCount;
  7. mItemCount = getAdapter().getCount();//Adapter现有元素个数
  8. if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
  9. && mOldItemCount == 0 && mItemCount > 0) {
  10. AdapterView.this.onRestoreInstanceState(mInstanceState);
  11. mInstanceState = null;
  12. } else {
  13. rememberSyncState();
  14. }
  15. checkFocus();
  16. requestLayout();//更新视图
  17. }
  18. .................
  19. }

AdapterDataSetObserver里的具体实现我没弄清楚,但感觉是在这里更新了ListView显示的数据,ListView里是怎样更新的没弄清楚,希望哪位高手知道的告诉我。

但是如果只在ListView里显示Adapter的部分数据,该怎么弄呢,可继承BaseAdapter,实现BaseAdapter里未实现的如下方法:

getCount()、getItem(int position)、getItemId(int position)、getView(int position, View convertView, ViewGroup parent)。

只需在getCount里返回想要的大小就行了。

最新文章

  1. getComputedStyle 方法
  2. Xcode 改时间问题 lua代码没反应问题
  3. Linux 查看磁盘空间大小
  4. Evolutionary Computing: 2. Genetic Algorithm(1)
  5. Android(Java):jni源代码
  6. Give My Text Back
  7. 【bzoj1052】覆盖问题
  8. oracle定时运行 存储过程
  9. sql 关于dblink和多条update、insert事务回滚写法
  10. java集合(1)- 类底层数据结构分析
  11. shell编程/字库裁剪(2)——编程过程
  12. spring 学习笔记1
  13. P1471 方差
  14. Aviator 表达式求值引擎开源框架
  15. 20145209刘一阳《JAVA程序设计》第二周课堂测试
  16. 使用git 将自己的本地文件git到github上面的完整过程
  17. centos启动zookeeper
  18. 【bzoj1858】[Scoi2010]序列操作 线段树区间合并
  19. HDU1165: Eddy&#39;s research II(递推)
  20. Ajax 请求session过期的统一处理

热门文章

  1. MyBatis3-示例工程
  2. VB的程序如何破解
  3. 利用FFmpge进行视频压缩(从图像到H264视频流)
  4. LLDB 常用命令
  5. svn 运行clear up 失败的解决的方法
  6. 2015南阳CCPC H - Sudoku 数独
  7. 使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)
  8. 洛谷 P2055 [ ZJOI 2009 ] 假期的宿舍 —— 二分图匹配
  9. ckeditor详细设置
  10. codevs1312连续自然数和