最近由于遇到将内容分部绑定到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里返回想要的大小就行了。

registerDataSetObserver:浅析Andorid ListView和Adapte的更多相关文章

  1. andorid ListView和GirdView 与ScrollView 冲突

    1.listview解决方法 public static void setListViewHeightBasedOnChildren(ListView listView) { if(listView ...

  2. 从 ListView 到 RecyclerView 的用法浅析

    文章目录 要走好明天的路,必须记住昨天走过的路,思索今天正在走着的路. ListView,一种在垂直滚动列表中显示条目的视图:RecyclerView,一种在局限的窗口呈现大数据集合的灵活视图.Rec ...

  3. 安卓高级2 swipeReferenceLayout 使用案例 和完善其自定义上拉

    swipeReferenceLayout 无法完成上来加载数据所以自定义了一个类 Activity.java package qianfeng.com.swipelayoutdemo; import ...

  4. RxJava RxBinding RxView 控件事件 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. [转]Android ListView 与 RecyclerView 对比浅析—缓存机制

    从源码角度剖析ListView 与 RecyclerView 缓存机制的不同 https://zhuanlan.zhihu.com/p/23339185 原文地址:http://dev.qq.com/ ...

  6. 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...

  7. RecyclerView与ListView 对比浅析:缓存机制

    一. 背景 PS:相关知识:ListView与RecyclerView缓存机制原理大致相似,如下图所示: 滑动过程中,离屏的ItemView即被回收至缓存,入屏的ItemView则会优先从缓存中获取, ...

  8. ListView与RecyclerView对比浅析——缓存机制

    https://www.jianshu.com/p/193fb966e954 一,背景 RecyclerView是谷歌官方出的一个用于大量数据展示的新控件,可以用来代替传统的ListView,更加强大 ...

  9. andorid 列表视图 ListView 之BaseAdapter

    .xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android=&qu ...

随机推荐

  1. MyBatis3错误:Parameter 'id' not found. Available parameters are [arg2, arg1, arg0, param3, param1, param2]或者Parameter '0' not found. Available parameters are [arg2, arg1, arg0, param3, param1, param2]

    这个问题涉及到MyBatis3在使用select节点查询时传递多个参数的问题.问题分析如下: 1.如果是单个查询一般是这样配置: <select id="getUserArticles ...

  2. 网络请求之GET、POST请求

    网络请求-GET请求: 1,NSURL: 请求地址. 2,NSURLRequest :一个NSURLRequest对象就代表一个请求.它包括的信息有: 1)一个NSURL对象 GET请求,不须要写请求 ...

  3. 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变

    在net中json序列化与反序列化   准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...

  4. zTree初体验(一)——小试牛刀

    zTree 是一个依靠 jQuery 实现的多功能 "树插件".优异的性能.灵活的配置.多种功能的组合是 zTree 最大长处. --zTree官网 zTree v3.0 将核心代 ...

  5. LeetCode 819. Most Common Word (最常见的单词)

    Given a paragraph and a list of banned words, return the most frequent word that is not in the list ...

  6. cocos2dx 编译时间长问题

    { F:\cocos2dx\cocos2d-x-3.7.1\templates\cpp-template-default 彻底解决方式 为把cocos的模版项目编译好(详细是所有生成好并清理Hello ...

  7. Delphi中ARC内存管理的方向

    随着即将发布的10.3版本,RAD Studio R&D和PM团队正在制作Delphi在内存管理方面的新方向. 几年前,当Embarcadero开始为Windows以外的平台构建新的Delph ...

  8. Linux基本命令 文件管理 下部

    1.1 移动文件 将/data目录移动到/root下 涉及命令mv [root@oldboyedu-50 ~]# mv /data/ /root/ 移动 [root@oldboyedu-50 ~]# ...

  9. codevs1026商务旅行

    1036 商务旅行  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 某首都城市的商人要经常到各城镇去做 ...

  10. iview日期选择框,获取的日期总是少一天

    使用iview的datepicker时间选择器发现获取的value值是比实际要少一天,严格来说应该是时间格式不一样,datepicker获取的时间是UTC时间 格式,也就是:yyyy-MM-ddTHH ...