很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性。查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷新和上拉加载更多。这个组件有个mode的属性,可以设置为both,即上下同时都可拉动。但是只设置这个属性的话,上拉与下拉产生的效果是完全一致的。所以要使用这个开源项目做到下拉刷新并同时可上拉加载更多,就需要在代码中进行一些处理。

==========================pulltorefresh属性相关=====================================

开源项目:

项目地址:

1.属性:

命名空间: xmlns:ptr=""

ptr:ptrAnimationStyle 动画效果 提供了两个值 flip和rotate 默认为rotate
ptr:ptrRefreshableViewBackground 设置刷新View的背景颜色
ptr:ptrHeaderBackground 设置头部View的背景颜色
ptr:ptrHeaderTextColor 设置头部View文字的颜色
ptr:ptrHeaderSubTextColor 设置头部view副标题文字的颜色
ptr:ptrMode

pullFromStart:

pullFromEnd:

both;

2.常用方法

setOnRefreshListener(OnRefreshListener listener):设置刷新监听器;

setOnLastItemVisibleListener(OnLastItemVisibleListener listener):设置是否到底部监听器;

setOnPullEventListener(OnPullEventListener listener);设置事件监听器;

onRefreshComplete():设置刷新完成

==========================监听listview滚动方向=====================================

修改为上拉加载更多的关键在于onrefresh方法执行之前判断出listview的滚动方向。以下方法是所尝试的方法中效果最好的一种,并不能说完美解决,但应该是效果最接近的一种了。(当首屏数据行数未充满屏幕,或者滚动时第一行的滚动距离小于行高,可能还是会存在一点误差。不过大部分应用的列表每页数据一般都能充满屏幕,也可在此基础结合其他手势判断对此方法进行改善)。

int mLastFirstVisibleItem = 0;boolean mIsScrollingUp;@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState){                                                                                                         if (view.getId() == mListView.getId())    {        final int currentFirstVisibleItem = mListView.getFirstVisiblePosition();                                                                                                                 if (currentFirstVisibleItem > mLastFirstVisibleItem)        {            mIsUp = true;        }        else if (currentFirstVisibleItem < mLastFirstVisibleItem)        {            mIsUp = false;        }        mLastFirstVisibleItem = currentFirstVisibleItem;    }                                                                                                     }

参考资料:http://stackoverflow.com/questions/12114963/detecting-the-scrolling-direction-in-the-adapter-up-down/12115157#12115157

==========================实现下拉刷新和上拉加载更多====================================

解析json完毕后,判断是上拉操作还是下拉刷新操作:

// 解析jsonprivate void parseJson(String result){    List
 localList = parseJsonArray(Utils.parseListJson(result, "key"));                                                             if(!mIsUp)    {        mDataList.clear();    }    mDataList.addAll(localList);}

数据加载完毕后,notifyDataSetChanged和通知PullRefreshListView,同时页码加1:

// 加载完毕处理private void loadComplete(){    mPullRefreshListView.onRefreshComplete();    mAdapter.notifyDataSetChanged();    mPage += 1;}

判断上拉和下拉方向,监听刷新listview,修改头部和底部view的文字说明:

/** * *******************下拉刷新与上拉加载的监听处理************************ */// 刷新listview监听@Overridepublic void onRefresh(PullToRefreshBase
 refreshView){    // 获取刷新时间,设置刷新时间格式    String str = DateUtils.formatDateTime(getActivity(), System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);                     // 判断下拉还是上拉    if (!mIsUp)        mPage = 0;                     // 设置刷新文本说明(刷新过程中)    if (mIsUp)    {        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后加载时间:" + str);    }    else    {        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉刷新");        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后更新时间:" + str);    }                     // 启动下载任务,加载数据    loadTask();}int mLastFirstVisibleItem = 0;boolean mIsScrollingUp;@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState){                     if (view.getId() == mListView.getId())    {        final int currentFirstVisibleItem = mListView.getFirstVisiblePosition();                             if (currentFirstVisibleItem > mLastFirstVisibleItem)        {            mIsUp = true;        }        else if (currentFirstVisibleItem < mLastFirstVisibleItem)        {            mIsUp = false;        }        mLastFirstVisibleItem = currentFirstVisibleItem;    }                 }@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){    // 设置刷新文本说明(展开刷新栏前)    if (mIsUp)    {        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");    }    else    {        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉刷新");        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");    }                 }@Overridepublic void onLastItemVisible(){    mIsUp = true;}

==========================其他使用笔记====================================

1.PullRefreshListView.setRefreshing()方法无法执行更新

@Override    protected void onRefreshing(final boolean doScroll) {        /**         * If we're not showing the Refreshing view, or the list is empty, the         * the header/footer views won't show so we use the normal method.         */        /*ListAdapter adapter = mRefreshableView.getAdapter();        if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {            super.onRefreshing(doScroll);            return;        }*/        super.onRefreshing(false);        }    }

mPullRefreshListView.setRefreshing();如果adapter是里面的size是null 或者大小是0

这个时候 setRefreshing是不会有效果的.需要将PullToRefreshListView上面代码注释掉

2.通过继承OnRefreshListener2<ListView>直接实现上拉与下拉监听,但是下拉窗口的文字无法及时更新,即方法只在下拉操作后才执行。

        mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.refresh_listview);        mListView = ((ListView) this.mPullRefreshListView.getRefreshableView());                // 监听listview        mPullRefreshListView.setOnRefreshListener(this);        // mPullRefreshListView.setOnRefreshListener(this);        // mPullRefreshListView.setOnLastItemVisibleListener(this);        // mPullRefreshListView.setOnScrollListener(this);         mPullRefreshListView.setOnItemClickListener(this);

相应接口方法:

    @Override    public void onPullDownToRefresh(PullToRefreshBase
 refreshView)    {        // 获取刷新时间        String str = DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);                // 设置刷新文本说明(刷新过程中)        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉刷新");        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后更新时间:" + str);                onPullDownListView();    }        public void onPullDownListView()    {        // TODO Auto-generated method stub            }    @Override    public void onPullUpToRefresh(PullToRefreshBase
 refreshView)    {        // 获取刷新时间        String str = DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);                // 设置刷新文本说明(刷新过程中)        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后加载时间:" + str);                onPullUpListView();    }    public void onPullUpListView()    {        // TODO Auto-generated method stub            }