ListView分页技术研究01

1. 实现如下效果

image

说明:

(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);
        }
    };

未完,待续。。。。。。。

 

 

 

你可能感兴趣的:(ListView)