前言

  以前在实现ListView下拉刷新和上拉加载数据的时候都是去继承原生的ListView重写它的一些方法,实现起来非常繁杂,需要我们自己去给ListView定制下拉刷新和上拉加载的布局文件,然后添加ScrollView和OnTouch监听,设置回调接口获取数据,为了更好的交互体验,我们还不能直接利用setVisibility隐藏显示布局等等一大堆的操作,累都累死了。(题外话:关于下拉刷新在新版的android-support-v4.jar里,其实谷歌已经为我们提供了一个控件叫SwipeRefreshLayout,使用方法也非常简单,有兴趣的朋友可以自己网上了解下)它的实现效果大致是这样的:

  今天来说下关于开源项目PullToRefresh的使用方法,轻轻松松几行代码就可以把下拉刷新和上拉加载功能给实现了。(开源的东西虽然好用,但作为学习,还是建议大家先不用开源组件自己去实现一遍所需要的效果,毕竟原理需要懂),好了,言归正传,我尽量的言简意赅,进入主题。

先看下最后的实现效果图:

  

准备工作

1、既然是利用PullToRefresh组件来实现下拉刷新和上拉加载数据的效果,那么首先我们需要先把它下载下来。

这是PullToRefresh在GitHub上的下载地址:https://github.com/chrisbanes/Android-PullToRefresh/wiki/Quick-Start-Guide

很简单,下载完毕后我们就可以开始进入开发工作了。

磨刀不误砍柴工

1、首先先导入该项目

在导入项目后,我们会发现出现了很多红叉,不用担心,这个只是引用库路径出错罢了,我们右键点击有红叉的文件选择Properties,选择Andorid下拉,把对应的library重新 引入即可,依样画葫芦,其他出现的红叉的文件也都这样做。

  

把红叉都解决完之后,有个很重要的事情要做,把刚导入的所有文件夹里的android-support-v4.jar和你自己的项目里的v4包统一了,避免v4包版本不一致导致项目运行出错。

干活干活!

布局文件,非常简单,只放了一个可下拉刷新的ListView

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"> <com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="@+id/mylistview"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</com.handmark.pulltorefresh.library.PullToRefreshListView> </RelativeLayout>

主代码文件:

 package com.rabbit.pulltorefreshdemo;

 import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView; import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshListView; public class MainActivity extends Activity { //声明下拉刷新ListView组件
private PullToRefreshListView myListView;
//声明数据源
private List<String> data;
//声明适配器
private ArrayAdapter<String> adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取下拉刷新ListView组件
this.myListView=(PullToRefreshListView) findViewById(R.id.mylistview);
//模拟数据
this.data=new ArrayList<String>();
data.add("JAVA");
data.add("PHP");
data.add("C++");
data.add("C#");
//实例化Adapter
this.adapter=new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, data);
//设置Adapter
myListView.setAdapter(adapter);
//设置支持上下拉动和监听
myListView.setMode(Mode.BOTH);
myListView.setOnRefreshListener(new OnRefreshListener<ListView>() { @Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) { if(refreshView.isShownHeader()){
//判断头布局是否可见,如果可见执行下拉刷新
//设置尾布局样式文字
myListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");
myListView.getLoadingLayoutProxy().setPullLabel("下拉刷新数据");
myListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");
//模拟加载数据线程休息3秒
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(3000);
data.add("刷新数据1");
data.add("刷新数据2");
data.add("刷新数据3");
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
} @Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//完成对下拉刷新ListView的更新操作
adapter.notifyDataSetChanged();
//将下拉视图收起
myListView.onRefreshComplete();
}
}.execute();
}
if(refreshView.isShownFooter()){
//判断尾布局是否可见,如果可见执行上拉加载更多
//设置尾布局样式文字
myListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");
myListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");
myListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");
//模拟加载数据线程休息3秒
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(3000);
data.add("更多数据1");
data.add("更多数据2");
data.add("更多数据3");
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
} @Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//完成对下拉刷新ListView的更新操作
adapter.notifyDataSetChanged();
//将下拉视图收起
myListView.onRefreshComplete();
}
}.execute(); } }
}); } }

其实和普通ListView的使用方式差不多,只是多了一些属性的设置,这里有几个要注意的地方:

1、模式的设置,默认下PullToRefresh的刷新模式只支持下拉刷新,我们可以通过setMode(Mode.XXXX)来设置它

 BOTH:上拉刷新和下拉刷新都支持
DISABLED:禁用上拉下拉刷新
PULL_FROM_START:仅支持下拉刷新(默认)
PULL_FROM_END:仅支持上拉刷新
MANUAL_REFRESH_ONLY:只允许手动触发

2、补充上述描述第1点,当我们设置模式为BOTH的时候,我们就可以实现下拉和上拉了,但这里的它们的样式是一样的,我们需要的场景应该是下拉的时候显示"下拉刷新数据,正在刷新数据,数据刷新成功....",而在我们上拉的时候应该出现的场景是"上拉加载数据,正在加载数据,加载数据成功...",所以这里我们需要对样式进行设置。

由于PullToRefresh默认是没给我们判断到底是上拉还是下拉的方法,所以我们需要去源代码里修改下它的代码,Ctrl+Shift+T搜索下PullToRefreshBase类,打开后再后最后面我们补上这样一段代码,我们可以根据当头布局可见的时候执行下拉刷新,当尾布局可见的时候执行下拉加载,这样我们就可以根据头尾布局来判断用户到底是执行上拉还是下拉操作了。

     //判别头部是否展示出来,如果展示出来代表下拉使得头部展示。true为下拉
public boolean isShownHeader() {
return getHeaderLayout().isShown();
}
//判别低部是否展示出来,如果展示出来代表上拉使得低部展示。true为上拉
public boolean isShownFooter() {
return getFooterLayout().isShown();
}

3、这是关于PullToRefresh的一些属性设置,在源码中可以找到,这里我做了下翻译:

 <?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PullToRefresh">
<!-- A drawable to use as the background of the Refreshable View -->
<!-- 设置整个刷新列表的背景色 -->
<attr name="ptrRefreshableViewBackground" format="reference|color" />
<!-- A drawable to use as the background of the Header and Footer Loading Views -->
<!-- 设置下拉Header或者上拉Footer的背景色 -->
<attr name="ptrHeaderBackground" format="reference|color" />
<!-- Text Color of the Header and Footer Loading Views -->
<!-- 用于设置Header与Footer中文本的颜色 -->
<attr name="ptrHeaderTextColor" format="reference|color" />
<!-- Text Color of the Header and Footer Loading Views Sub Header -->
<!-- 用于设置Header与Footer中上次刷新时间的颜色 -->
<attr name="ptrHeaderSubTextColor" format="reference|color" />
<!-- Mode of Pull-to-Refresh that should be used -->
<attr name="ptrMode">
<flag name="disabled" value="0x0" /><!-- 禁用下拉刷新 -->
<flag name="pullFromStart" value="0x1" /><!-- 仅支持下拉刷新 -->
<flag name="pullFromEnd" value="0x2" /><!-- 仅支持上拉刷新 -->
<flag name="both" value="0x3" /><!-- 上拉刷新和下拉刷新都支持 -->
<flag name="manualOnly" value="0x4" /><!-- 只允许手动触发 --> <!-- These last two are depreacted -->
<flag name="pullDownFromTop" value="0x1" />
<flag name="pullUpFromBottom" value="0x2" />
</attr>
<!-- Whether the Indicator overlay(s) should be used -->
<!-- 如果为true会在mPullRefreshListView中出现icon,右上角和右下角,挺有意思的 -->
<attr name="ptrShowIndicator" format="reference|boolean" />
<!-- Drawable to use as Loading Indicator. Changes both Header and Footer. -->
<!-- 同时改变头部和底部的图标 -->
<attr name="ptrDrawable" format="reference" />
<!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. -->
<!-- 头部视图的图标-->
<attr name="ptrDrawableStart" format="reference" /> <!-- Drawable to use as Loading Indicator in the Footer View. Overrides value set in ptrDrawable. -->
<!-- 底部视图的图标 -->
<attr name="ptrDrawableEnd" format="reference" />
<!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. -->
<attr name="ptrOverScroll" format="reference|boolean" />
<!-- Base text color, typeface, size, and style for Header and Footer Loading Views -->
<!-- 分别设置拉Header或者上拉Footer中字体的类型颜色等等 -->
<attr name="ptrHeaderTextAppearance" format="reference" />
<!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header -->
<attr name="ptrSubHeaderTextAppearance" format="reference" />
<!-- Style of Animation should be used displayed when pulling. -->
<attr name="ptrAnimationStyle">
<flag name="rotate" value="0x0" /><!-- flip(翻转动画), rotate(旋转动画) -->
<flag name="flip" value="0x1" />
</attr>
<!-- Whether the user can scroll while the View is Refreshing -->
<!-- 刷新的时候,是否允许ListView或GridView滚动 -->
<attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" />
<!--
Whether PullToRefreshListView has it's extras enabled. This allows the user to be
able to scroll while refreshing, and behaves better. It acheives this by adding
Header and/or Footer Views to the ListView.
-->
<!-- 决定了Header,Footer以何种方式加入mPullRefreshListView,true为headView方式加入,就是滚动时刷新头部会一起滚动 -->
<attr name="ptrListViewExtrasEnabled" format="reference|boolean" />
<!--
Whether the Drawable should be continually rotated as you pull. This only
takes effect when using the 'Rotate' Animation Style.
-->
<attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" />
<!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. -->
<attr name="ptrAdapterViewBackground" format="reference|color" />
<attr name="ptrDrawableTop" format="reference" />
<attr name="ptrDrawableBottom" format="reference" />
</declare-styleable>
</resources>

设置属性也很简单,在对应的布局文件里直接设置就可以,比如字体颜色:

     <com.handmark.pulltorefresh.library.PullToRefreshListView
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="@+id/lv_friendsline"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
ptr:ptrHeaderTextColor="#000000"
>

其他的一些,大家看我代码注释吧,写的非常详细了。

补充:关于这个PullToRefresh它不仅仅支持ListView,比如ScrollView,GridView等等,只要是能滚动到控件它都通吃,具体使用方法大家可以参考我们一开始导入的项目里的LauncherActivity。

作者:Balla_兔子
出处:http://www.cnblogs.com/lichenwei/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!

安卓开发笔记——关于开源组件PullToRefresh实现下拉刷新和上拉加载(一分钟搞定,超级简单)的更多相关文章

  1. IOS 开发下拉刷新和上拉加载更多

    IOS 开发下拉刷新和上拉加载更多 简介 1.常用的下拉刷新的实现方式 (1)UIRefreshControl (2)EGOTTableViewrefresh (3)AH3DPullRefresh ( ...

  2. Android 使用PullToRefresh实现下拉刷新和上拉加载(ExpandableListView)

    PullToRefresh是一套实现非常好的下拉刷新库,它支持: 1.ListView 2.ExpandableListView 3.GridView 4.WebView 等多种常用的需要刷新的Vie ...

  3. 使用PullToRefresh实现下拉刷新和上拉加载

    使用PullToRefresh实现下拉刷新和上拉加载 分类: Android2013-12-20 15:51 78158人阅读 评论(91) 收藏 举报 Android下拉刷新上拉加载PullToRe ...

  4. Diycode开源项目 搭建可以具有下拉刷新和上拉加载的Fragment

    1.效果预览 1.1.这个首页就是一个Fragment碎片,本文讲述的就是这个碎片的搭建方式. 下拉会有一个旋转的刷新圈,上拉会刷新数据. 1.2.整体结构 首先底层的是BaseFragment 然后 ...

  5. vue2.0 自定义 下拉刷新和上拉加载更多(Scroller) 组件

    1.下拉刷新和上拉加载更多组件 Scroller.vue <!-- 下拉刷新 上拉加载更多 组件 --> <template> <div :style="mar ...

  6. jQuery WeUI 组件下拉刷新和滚动加载的实现

    最近在做手机版使用到了下拉刷新和滚动加载,记录一下实现过程: 一.引入文件 ? 1 2 3 4 <link rel="stylesheet" href="Conte ...

  7. 安卓开发笔记——关于开源项目SlidingMenu的使用介绍(仿QQ5.0侧滑菜单)

    记得去年年末的时候写过这个侧滑效果,当时是利用自定义HorizontalScrollView来实现的,效果如下: 有兴趣的朋友可以看看这篇文件<安卓开发笔记——自定义HorizontalScro ...

  8. 安卓开发笔记——Fragment+ViewPager组件(高仿微信界面)

    什么是ViewPager? 关于ViewPager的介绍和使用,在之前我写过一篇相关的文章<安卓开发复习笔记——ViewPager组件(仿微信引导界面)>,不清楚的朋友可以看看,这里就不再 ...

  9. 安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)

    记得之前写过2篇关于底部菜单的实现,由于使用的是过时的TabHost类,虽然一样可以实现我们想要的效果,但作为学习,还是需要来了解下这个新引入类FragmentTabHost 之前2篇文章的链接: 安 ...

随机推荐

  1. 安卓开发-Activity中finish() onDestroy() 和System.exit()的区别(转)

    Activity.finish()Call this when your activity is done and should be closed. 在你的activity动作完成的时候,或者Act ...

  2. Qt 4.6.2静态编译后,创建工程出现中文乱码的解决办法

    一.如果静态编译是用mingw编译的 1)在pro文件里增加QTPLUGIN += qcncodecs 2)在main函数所在的文件里面增加#include <QtPlugin>和Q_IM ...

  3. reveal查看任意APP

    链接: 使用Reveal查看任意App的技巧 使用Reveal查看任意App最省步骤的技巧 如何利用Reveal神器查看各大APP UI搭建层级 使用Reveal查看别人app的UI组成 Reveal ...

  4. 数据结构C语言版--动态顺序表的基本功能实现(二)

    /* * 若各个方法结构体变量参数为: &L(即地址符加变量)则结构体变量访问结构成员变量时使用"." * 若为:*L(即取地址符加变量)则结构体变量访问结构体成员变量使用 ...

  5. 17、python对内存的使用

    python对内存的使用 浅拷贝和深拷贝 所谓浅拷贝就是对引用的拷贝(只拷贝父对象) 所谓深拷贝就是对对象的资源的拷贝 解释一个例子: import copy a = [1,2,3,['a','b', ...

  6. 还在为工作发愁?学JavaScript吧

    事实上,每家专业招聘机构,从Glassdoor.com和Linkedin到美国劳工部,都报导了就业市场对开发人员需求的增长速度出于意料地快.这种需求可能已经不新鲜了,但是就业市场对哪种开发语言的需求量 ...

  7. CentOS中环境变量和配置文件

    什么是环境变量 bash shell用一个叫做 环境变量(environment variable) 的特性来存储有关shell会话和工作环境的信息.即允许在内存中存储数据,使得在程序或shell中运 ...

  8. SSE图像算法优化系列一:一段BGR2Y的SIMD代码解析。

    一个同事在github上淘到一个基于SIMD的RGB转Y(彩色转灰度或者转明度)的代码,我抽了点时间看了下,顺便学习了一些SIMD指令,这里把学习过程中的一些理解和认识共享给大家. github上相关 ...

  9. git的使用笔记

    1.git下载:https://git-scm.com/downloads   安装git   2.在github.com网站上注册账号 网址:https://github.com/   3.使用gi ...

  10. PowerShell使用ServicePrincipal登陆Azure

    一.打开PowerShell 二.输入下列命令 $pass = ConvertTo-SecureString "<这里换成您的AAD应用密钥>" -AsPlainTex ...