ListView分页技术研究01
1. 实现如下效果
说明:
(1) “prepage”,“nextpage”等都是Button控件,“3/10”为TextView控件
(2) 将button和TextView封装在一个自定义的混合组件PageBar中
(3) 当前页面处于第一页的时候,不显示headerView,当前页面处于最后一页的时候,不显示footerView
(4) 对于显示在ListView中的数据,要保存起来,当再次浏览这一页的时候,就不用重新请求了。在Adapter中使用hashmap存储这些数据,键为页码,值为存储每页数据的List集合。
2. 实现功能
2.1 每页显示10条数据,
2.2 当点击“prepage”,“nextpage”的时候,就去请求数据,如果Adapter中已经有了这些数据,则直接从Adapter中获取,如果Adapter中没有,则去请求服务器。
2.3 请求服务器如何实现:
将所有的AsyncTask全部放在Activity中,由Activity控制这些异步任务的生命周期
3. 难点
3.1 通过解析xml的形式得到自定义组件PageBar的实例对象,但是一个ListView有一个headerView,还有一个footerView,这两个view只是显示内容不同,如果headerView和footerView使用同一个pageBar实例的话,那么控制显示内容是个很繁琐的,暂时采用实例化两个实例对象来,分别作为headerView和footerView。这里有个问题,如何得到一个实例对象的完全一样的对象,我想到了克隆,但是还没有解决这个问题,留待以后研究。
3.2 添加,移除ListView的headerView或者是footerView需要注意的地方?
添加:关于addHeaderView方法文档上有这么一句话,“Call this before calling setAdapter”,在调用这个方法之前,先要设定ListView的Adapter。addFooterView方法同样
移除:用到了系统提供的removeHeaderView或者removeFooterView方法,虽然文档上没有说明,但是调用这个方法应该在setAdapter之后。实例验证,不知道为什么,应该好好看看。
3.3 ListView上添加了headerView或者footerView的时候,在onItemClick事件里出现了问题?
private OnItemClickListener mItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
JobsAdapter ad = (JobsAdapter) parent.getAdapter();
ad.toggle(position);
}
};报ava.lang.ClassCastException: android.widget.HeaderViewListAdapter异常?上述代码中红色的部分引起了这个异常?
首先来看看ListView的setAdapter方法:
public void setAdapter(ListAdapter adapter) {
if (null != mAdapter) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();
mRecycler.clear();if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
} else {
mAdapter = adapter;
}…………
requestLayout();
}红色代码的意思是如果ListView没有headerView或者footerView的时候,与listView相关联的Adapter就是传进来的参数Adapter,如果有,就将原来的Adapter包装成HeaderViewListAdapter,看看HeaderViewListAdapter的文档说明:
ListAdapter used when a ListView has header views. This ListAdapter wraps another one and also keeps track of the header views and their associated data objects.
This is intended as a base class; you will probably not need to use this class directly in your own code.
HeaderViewListAdapter有个方法getWrappedAdapter,该方法能返回被包装的HeaderViewListAdapter的ListAdapter。
到了这里就明白为什么会报ClassCastException异常了。因为ListView的getAdapter方法返回的是HeaderViewListAdapter的实例,而将其转换成BaseAdapter的子类的实例,肯定是不对的。
由于ListView添加了headerView或者footerView,所以就相当于给ListView的数据添加了两项,加了个headerView,所以其他的view在界面上的位置position都增长了1,所以当用户点击界面上的第二项的时候,实际上点的是第三项,这就涉及到了ListView中的position和自定义Adapter中的position的对应关系问题了,将onItemClick改成下面的写法就好了。
private OnItemClickListener mItemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
HeaderViewListAdapter ha = (HeaderViewListAdapter) parent.getAdapter();
JobsAdapter ad = (JobsAdapter) ha.getWrappedAdapter();
ad.toggle(position-1);
}
};未完,待续。。。。。。。