1.简介
ListView
是Android使用频率非常高的一个控件,它以列表的形式展示内容,并且能够根据数据的长度自适应高度。
2.展示列表所需要的元素组成
1.需要用来展示列表的
ListView
2.用来组织数据并映射到ListView
的Adapter
3.需要展示的数据集
4.需要展示的View
模板
3.各组成之间的关系
ListView
只负责加载、管理视图,至于有多少数据,每一项数据要怎么来展示,这些它都不关心。Adapter
使用Adapter
模式,使用抽象方式将用户需要指定的数据抽象出来,让用户去实现。比如:有多少数据需要展示、用什么方式来进行展示等等。
需要实现的Adapter
的函数为:
1.getCount():指定当前有多少数据需要展示
2.getItem(int):获取当前position
位置的数据
3.getItemId(int):直接返回当前对应的position
4.getView(int,View,ViewGroup):返回当前position
对应的item
的view
4.ListView原理
当处理较大的数据时,Listview
并不是一次性加载所有数据,而是只加载铺满整个屏幕的数据。当屏幕向下滚动时,第一个元素离开了屏幕之后会进入到Listview
里的一个Recycler
集合中,Recycler
会将当前视图缓存。这时最下面需要填充一个新的元素,ListView
会先去Recycler
集合里去取,如果有就会复用此视图,如果没有就接着创建。通过getView(int,View,ViewGroup)
方法将所取到的数据传递给用户来进行复用,如果没有传递的convertView
将为null
.
上面这张图很好的说明了ListView
的复用原理。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View mView = null;
if (convertView != null)
mView = convertView;
else {
//重新加载视图
mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, null);
}
//这里将数据和视图进行绑定
return mView;
}
这里的position
表示当前item
是第几项数据,convertView
表示缓存的item view
,parent
表示item view
的父视图,这里所指的就是我们的Listview
。这里最重要的就是convertView
,如果convertView
不为空,可以直接复用该视图,如果为空,就要重新创建视图,最后返回当前item
所对应的已绑定数据的view
.
5.ListView设计模式解析
listView
运用了Adapter
模式,而在Adapter
类中却还运用了观察者模式,Adapter
内部有一个被观察者类,ListView
作为它的一个观察者,在将Adapter
设置给ListView
时,ListView
就被当作观察者注册到了Adapter
内的被观察者对象上了。
我们以ListView
的数据刷新来通过源码实现来看看其设计模式
@Override
public void setAdapter(ListAdapter adapter) {
//代码省略...
super.setAdapter(adapter);
//代码省略...
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
//代码省略...
}
上面源码说明在setAdapter
方法里创建了一个AdapterDataSetObserver
对象,并把该对象注册到了mAdapter
。
再来看看我们Adapter
的父类BaseAdapter
在BaseAdapter
基类中我们看到了上面的AdapterDataSetObserver
类被注册到了DataSetObservable
被观察者对象中。
接下来我们来看看DataSetObservable
类
从图上可以看出DataSetObservable
就是继承了Java
提供的被观察者对象,并通过notifyChanged
来通知注册了的观察者对象。
到这里还是没有看到ListView
注册了Adapter
。而注册的是AdapterDataSetObserver
对象。那我们就去看看这个AdapterDataSetObservable
这个对象的实现吧。
从图上可以看出,这是一个典型的Observer的实现,通过实现onChanged
来接收被观察都传递过来的数据。在onChanged
方法里调用了父类的方法,我们去父类一探究竟。
在AdapterDataSetObserver
的onChanged
方法中,我们获取了item
的个数,以及调用requestLayout
方法来进行重新布局,绘制整个listView
的item View
.执行完此过程后,ListView
中的数据就得到了刷新。
这里的AdapterDataSetObserver
对象里调用的都是AdapterView
或者ViewGroup
类的属性或方法完成功能.而ListView
继承自AdapterView
.因此,只可以说AdapterDataSetObserver
只是在外层做了一下包装,核心的功能应该是ListView
,确切的说是AdapterView
。ListView
通过Adapter
模式、观察者模式、以及使用item View
复用来高效的展示列表数据