很多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. Java进阶之路,技术要点

    宏观方面 一.JAVA.要想成为JAVA(高级)工程师肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA(高级)工程师,您要对JAVA做比较深入的研究.您 ...

  2. 【转载】SQL server connection KeepAlive

    1.什么是SQL server TCP连接的keep Alive? 简单说,keep alive 是SQL server在建立每一个TCP 连接的时候,指定了TCP 协议的keepaliveinter ...

  3. 转 linux任务调度之crontab命令

    crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读取和执行. 在 ...

  4. SpringCloud集群(三)

    一.构造步骤 1.进行其他的服务中心的域名映射 127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.com 2 ...

  5. 【拓扑排序topsort】【p1226】神经网络

    描述 Description 神经网络就是一张有向图,图中的节点称为神经元,而且两个神经元之间至多有一条边相连,下图是一个神经元的例子: 神经元[编号为1) 图中,X1—X3是信息输入渠道,Y1-Y2 ...

  6. KVM Network Bridging

    from http://hzqtc.github.io/2012/02/kvm-network-bridging.html http://wiki.ubuntu.org.cn/Kvm_%E7%BD%9 ...

  7. html 基础二

    HTMLCSS基础2 一.HTML中的标签 1.1标签的特点 给文本加上含有语义的标签 应该学习更多具体语义标签 标签:用“<>”包起来的内容 2.1 更多的标签 2.1.1 h系列的标签 ...

  8. Persisting iOS Application Data in SQLite Database Using FMDB

    In previous articles we have utilized NSUserDefaults and .NET web services to persist iPhone data. N ...

  9. 用js怎么控制submit提交表单

    需求: 1. 要在点击submit按钮的时候,弹出一个询问框,"你确定要修改?".如果按了"确定"那么就提交表单,否则就保留在原页面,既不提交不跳转. 2. 要 ...

  10. 关于#include文件包含

    1.对于函数头文件: #include <filename> 一般对于标准库文件以一个.h后缀结尾: 2.对于本地文件: #include "filename.h" 对 ...