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

简介:

很多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;


2.常用方法

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

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

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

onRefreshComplete():设置刷新完成


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


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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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完毕后,判断是上拉操作还是下拉刷新操作:

1
2
3
4
5
6
7
8
9
10
11
// 解析json
private  void  parseJson(String result)
{
     List<ListJson> localList = parseJsonArray(Utils.parseListJson(result,  "key" ));
                                                          
     if (!mIsUp)
     {
         mDataList.clear();
     }
     mDataList.addAll(localList);
}


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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
  * *******************下拉刷新与上拉加载的监听处理************************
  */
// 刷新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 ;
}




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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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>直接实现上拉与下拉监听,但是下拉窗口的文字无法及时更新,即方法只在下拉操作后才执行。

1
2
3
4
5
6
7
8
9
         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 );


相应接口方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
     @Override
     public  void  onPullDownToRefresh(PullToRefreshBase<ListView> 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<ListView> 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
         
     }




本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1312349,如需转载请自行联系原作者

目录
相关文章
|
24天前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
156 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
1月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
179 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
55 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
5月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
165 1
|
5月前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
195 2
|
2月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
111 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
2月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
43 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
4月前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
在 Android 开发中,选择合适的架构模式对于构建中大型项目至关重要。常见的架构模式有 MVVM、MVP、MVI、Clean Architecture 和 Flux/Redux。每种模式都有其优缺点和适用场景,例如 MVVM 适用于复杂 UI 状态和频繁更新,而 Clean Architecture 适合大型项目和多平台开发。选择合适的架构应考虑项目需求、团队熟悉度和可维护性。
117 6
|
5月前
|
前端开发 JavaScript 测试技术
Android适合构建中大型项目的架构模式全面对比
Android适合构建中大型项目的架构模式全面对比
81 2
|
5月前
|
编译器 Android开发
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目

热门文章

最新文章

  • 1
    Android历史版本与APK文件结构
    16
  • 2
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    6
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    14
  • 4
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 5
    【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
    64
  • 6
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    6
  • 7
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    7
  • 8
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    3
  • 9
    Android实战经验之Kotlin中快速实现MVI架构
    5
  • 10
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    5
  • 1
    【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
    64
  • 2
    android FragmentManager 删除所有Fragment 重建
    25
  • 3
    Android实战经验之Kotlin中快速实现MVI架构
    41
  • 4
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    41
  • 5
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    46
  • 6
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    156
  • 7
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    54
  • 8
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    73
  • 9
    Android历史版本与APK文件结构
    181
  • 10
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    54