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

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

开源项目: Android-PullToRefresh

项目地址: https://github.com/chrisbanes/Android-PullToRefresh/wiki/Quick-Start-Guide

1.属性: https://github.com/chrisbanes/Android-PullToRefresh/blob/master/library/res/values/attrs.xml

命名空间: xmlns:ptr=" http://schemas.android.com/apk/res-auto "

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

pullFromStart:

pullFromEnd:

both;

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

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

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

onRefreshComplete():设置刷新完成

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

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

int mLastFirstVisibleItem = 0;
boolean mIsScrollingUp;
@Override
public 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完毕后,判断是上拉操作还是下拉刷新操作:

// 解析json
private void parseJson(String result)
{
List<ListJson> 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监听
@Override
public void onRefresh(PullToRefreshBase<ListView> 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;
@Override
public 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;
} }
@Override
public 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("释放开始刷新");
} }
@Override
public void onLastItemVisible()
{
mIsUp = true;
} /////////////////////////////////////////////////////////////////////////////////////////
lvVideo.setOnScrollListener(new OnScrollListener() {                         @Override
                        public void onScrollStateChanged(AbsListView view, int scrollState) {
                                
                                switch (scrollState) {
                                
                                // 滚动之前,手还在屏幕上  记录滚动前的下标
                                case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                                        //view.getLastVisiblePosition()得到当前屏幕可见的第一个item在整个listview中的下标
                                        lvIndext=view.getLastVisiblePosition();
                                        break;
                                        
                                //滚动停止 
                                case OnScrollListener.SCROLL_STATE_IDLE:
                                        //记录滚动停止后 记录当前item的位置
                                        int scrolled=view.getLastVisiblePosition();
                                        //滚动后下标大于滚动前 向下滚动了
                                        if(scrolled>lvIndext){
                                                //scroll = false;
                                                UIHelper.ToastMessage(VideoMain.this,"菜单收起");
                                        }
                                        //向上滚动了
                                        else{
                                                UIHelper.ToastMessage(VideoMain.this,"菜单弹出");
                                                //scroll = true;
                                        }
                                        break; //////////////////////////////////////////////////////////////////////////////////////////////////////
OnScrollListener 的 onScroll() 有一个 firstVisibleItem 参数(第二个参数),向下滑动会越来越大,向上滑动就会越来越小,可以在滑动的时候存储一下这个值,然后再与当前值进行判断

 另外也可以通过view.getLastVisiblePosition() 判断,这个返回的则是屏幕底部。
 

Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向的更多相关文章

  1. Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView

    在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...

  2. Android 自定义 ListView 上下拉动“刷新最新”和“加载更多”歌曲列表

    本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码 ...

  3. Android如何定制一个下拉刷新,上滑加载更多的容器

    前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉 ...

  4. Android 下拉刷新上拉载入 多种应用场景 超级大放送(上)

    转载请标明原文地址:http://blog.csdn.net/yalinfendou/article/details/47707017 关于Android下拉刷新上拉载入,网上的Demo太多太多了,这 ...

  5. listview下拉刷新上拉加载扩展(二)-仿美团外卖

    经过前几篇的listview下拉刷新上拉加载讲解,相信你对其实现机制有了一个深刻的认识了吧,那么这篇文章我们来实现一个高级的listview下拉刷新上拉加载-仿新版美团外卖的袋鼠动画: 项目结构: 是 ...

  6. listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖

    本篇是基于上篇listview下拉刷新上拉加载扩展(二)-仿美团外卖改造而来,主要调整了headview的布局,并加了两个背景动画,看似高大上,其实很简单: as源码地址:http://downloa ...

  7. Android PullToRefresh (GridView 下拉刷新上拉加载)

    做这个需要自己去git hub上下载个pull-to-refresh 里面有个library为依赖包自己导到自己的项目中 (下载地址:https://github.com/chrisbanes/And ...

  8. Android的ListView分页功能(上滑加载更多)

    今天主要工作是将之前实现的各种ListView显示全部信息,优化成了每次加载几条数据,然后上滑的时候加载更多,底部显示一个进度条和一个文字提示,然后加载完毕后,将提示信息隐藏. 一边看教学视频一遍敲代 ...

  9. android ListView下拉刷新 上拉加载更多

    背景 最近在公司的项目中要使用到ListView的下拉刷新和上拉加载更多(貌似现在是个项目就有这个功能!哈哈),其实这个东西GitHub上很多,但是我感觉那些框架太大,而且我这个项目只用到了ListV ...

随机推荐

  1. 计蒜客 28202. Failing Components-最短路(Dijkstra) (BAPC 2014 Preliminary ACM-ICPC Asia Training League 暑假第一阶段第一场 B)

    B. Failing Components 传送门 题意就是单向图,从起点开始找最短路,然后统计一下个数就可以.方向是从b到a,权值为s. 直接最短路跑迪杰斯特拉,一开始用数组版的没过,换了一个队列版 ...

  2. HDU 2639 Bone Collector II【01背包 + 第K大价值】

    The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup&quo ...

  3. Combination Sum III - LeetCode

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  4. 【Linux】Linux下 环境变量/etc/profile、/etc/bashrc、~/.bashrc的区别【转】

    转自:http://blog.csdn.net/qiao1245/article/details/44650929 ------------------------------------------ ...

  5. selenium 调用方法

    #coding:utf-8 from selenium import webdriver url = "http://demo.testfire.net" chrome_optio ...

  6. react热加载失败

    react热加载失败 原因:路径名字大小写错误, 不是全部加载失败,有的时候可以用,有的时候不可以 热加载插件:webpack-dev-server

  7. 安全小测试:介绍一个简单web安全知识测试的网站

    https://websecurity.firebaseapp.com/ 一次测试一共7道题,最后有答案,可以反复做,每次随机抽题

  8. iframe.contentWindow 属性:关于contentWindow和contentDocument区分

    定义和用法 contentDocument 属性能够以 HTML 对象来返回 iframe 中的文档,可以通过所有标准的 DOM 方法来处理被返回的对象. 语法:frameObject.content ...

  9. Tomcat7.0源代码分析——启动与停止服务原理

    前言 熟悉Tomcat的project师们.肯定都知道Tomcat是怎样启动与停止的. 对于startup.sh.startup.bat.shutdown.sh.shutdown.bat等脚本或者批处 ...

  10. Linux expect 用法

    expect是建立在tcl基础上的一个工具,它用来让一些需要交互的任务自动化地完成. 因为expect是基于tcl的,所以需要你的系统中安装有tcl 检查是否安装tcl,expect [root@ma ...