很多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. 查看 Laravel 的 SQL 语句的方法

    在使用 Laravel 的 Eloquent 进行数据查询的时候,很多小伙伴都想看到背后执行的 SQL 语句到底是什么样的,这小笔录就是解决这个小问题的: 在 Providers/AppService ...

  2. 如何在 GitHub 建立个人主页和项目演示页面

    Git.GitHub.TortoiseGit ?http://www.cnblogs.com/guyoung/archive/2012/02/18/8030-.html GitHub Github官网 ...

  3. Ubuntu 14.04 LTS+SublimeText3+中文输入

    文本编辑器,我习惯用Sublime Text,因为很好用啊,至于那些大神们说的Vim, Emacs,我目前还用不上:Vim偶尔会用到,gedit也会常用到,emacs几乎没用过,也不会: 一.安装: ...

  4. Python与数据库[0] -> 数据库概述

    数据库概述 / Database Overview 1 关于SQL / About SQL 构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一 ...

  5. 洛谷——P1067 多项式输出

    P1067 多项式输出 题目描述 一元 n 次多项式可用如下的表达式表示: 其中,aixi称为 i 次项,ai 称为 i 次项的系数.给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该 ...

  6. Shellcode开发辅助工具shellnoob

    Shellcode开发辅助工具shellnoob   Shellcode开发的过程中会遇到很多繁杂的工作,如编译.反编译.调试等.为了减少这部分工作,Kali Linux提供了开发辅助工具shelln ...

  7. 九. 常用类库、向量与哈希3.Java语言包(java.lang)简介

    Java语言包(java.lang)定义了Java中的大多数基本类,由Java语言自动调用,不需要显示声明.该包中包含了Object类,Object类是整个类层次结构的根结点,同时还定义了基本数据类型 ...

  8. 用swift开发自己的MacOS锁屏软件(二)

    上一篇中尝试写了hello world,这一篇中,开始尝试锁屏功能 1.尝试查找swift有没有相关的函数,可以控制系统锁屏之类的,结果并没有找到 2.尝试查找cocoa有没有相关的接口,结果仍然没有 ...

  9. DIV层+CSS实现锁屏

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  10. sql server 性能调优 资源等待之内存瓶颈的三种等待类型

    原文:sql server 性能调优 资源等待之内存瓶颈的三种等待类型 一.概述 这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),S ...