0%

Android控件-ListView阅读

ListView是早期版本时候的常用控件,虽然现在基本都不用了,但我觉得用来学习肯定会有收获。本来想自己写,但是看到别人已经有写的很好的版本了,鉴于郭神的博客应该不会404,所以这里直接贴链接了。Android ListView工作原理完全解析

ListView类图

因为不知道内部类怎么画,所以这里用了虚线箭头表示 DataSetObserver 类可以调用到 AdapterView 中。这里 DataSetObservable 和 DataSetObserver 是Java提供的观察者模式的实现类。当我们调用 BaseAdapter.notifyDataSetChanged()的时候,就可以沿着箭头一路找到AdapterView,进而调用到它的子类中去。

AdapterView 和 AbsListView 都是虚基类,其中 AdapterView 提供了 emptyView 和 Adapter 等相关的机制,AbsListView 提供了View复用的 RecycleBin 的机制 。ListView则提供了具体的Layout方法和HeaderView,FooterView等机制。

这里通过观察者模式实现了View和数据的分离,View的操作如果修改了数据,则需要通过BaseAdapter的接口来处理,而BaseAdapter如果数据发生了变动,则通过notifyDataSetChanged()来通知View更新界面。

在ListView的代码中,有点意外的是添加子view的过程是在onLayout中调用的,在 onMeasure() 的时候 ListView 只能通过 Adapter的引用来拿到 itemView ,计算它们的大小。这也表示作为一个容器其实 子view 只是一个概念而已。 对于 Adapter提供的 count() 个数的view, ListView 仅仅添加在界面上显示出来的view作为子view,没有显示出来的甚至不是它的childView。

ListView 在使用 RecycleBin 缓存的时候,使用的是Viewgroup 的 attachview 和 detachView ,这两个方法和 addview ,removeView的区别在于它不会主动要求重绘。

在Listview中设置 emptyView的时候,根本没有把emptyView添加到控件树里面,只是根据 item 的数量来更新 emptyView 的visibility.

1
2
3
4
5
6
7
8
9
/**
*
* RecycleBin 有两级缓存 : ActiveViews 和 ScrapViews 。 ActiveViews 是指最初显示在屏幕上的布局中的那些view,layout结束阶* 段,所有的ActiveViews都会降级成 ScrapViews。 ScrapViews 表示旧的views,他们是可能被重用的view的集合。
*
* @see android.widget.AbsListView#setRecyclerListener(android.widget.AbsListView.RecyclerListener)
* @see android.widget.AbsListView.RecyclerListener
*/
class RecycleBin {
}