图解ListView的刷新过程

ListView是 Android 应用开发中,常见的视图类组件,其普及程度差不多与 HTML 中的Table一样。此类组件的本质是将数据,也就是Model,表现出现,但其本身不负责维护数据,属于“来料加工”。

那么ListView又是怎么获得数据渠道呢?答案就是Adapter,其顾名思义就是“适配器”。就像笔记本加入市电,需要用电源适配器一样,原始数据不大可能直接显示给用户,就需要一个数据适配器,转换成视图所支持的样子。

到这里,数据已经可以展现给用户了,但是还面临一个问题,即如果数据更新了,视图能不能将新数据替换旧数据?在 Android 中,掌控数据、充当 Controller 角色的是Activity,它应该是知道数据有变化的,同时,它还持有ViewAdapter

Class Diagram: View & Adapter & Observer

Class Diagram: View & Adapter & Observer

如果发现数据变更,那么Activity调用AdapternotifyDataSetChanged方法,随后ListView就刷新界面,这个看起来理所当然的流程背后,到底是怎么一个逻辑呢?不妨从类图中,并结合源代码,找到线索。

ListView的父类AbsListView有一个成员变量mDataSetObserver,当调用setAdapter时,这个变量将被赋值,正是这个内部的mDataSetObserver担负起了刷新列表的重任。如下代码所示:

        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }
        // 省略
        if (mAdapter != null) {
            // 省略
            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);
            // 省略
        }

可以看到,在mDataSetObserver被赋值之后,立即通过registerDataSetObserver方法,将其注册进mAdapter。这样,当mAdapternotifyDataSetChanged方法被调用的时候,这个mDataSetObserveronChanged方法将会被调用。

Sequence Diagram: List Refresh

Sequence Diagram: List Refresh

从时序图上看,1-4是当Adapter设置给AdapterView的过程,5-8是当数据源发生改变的过程。尽管ListView并没有显示地告诉,它怎么就知道数据源更新,但借助类图搭配时序图,相信真相也就是大白了,--个中原委不过如此。

1 Comment

amazon12322 1 月, 2013 at 2:22 下午

博主咨询你个事,昨晚我也申请了亚马逊ec2 ,当时扣了我1美元,之后我把信用卡换掉了,今早也不知道是手欠还是咋了,我又把信用卡弄回能扣钱的了,然后又被扣了1美元,邮件也没给发,很是莫名其妙
看了你又一个博文,你说发邮件咨询,怪我愚钝,找了半天也没找到ec2的email(客服),希望告知下。

Leave a comment

Your comment