一:实现区别下拉刷新和上拉加载

参考资料:http://blog.csdn.net/losetowin/article/details/18261389

在PullToRefresh的类库的com.handmark.pulltorefresh.library包下,打开PullToRefreshBase.java,在这个类的最后面添加代码。注意,需要重新添加library库。

//根据下拉和上拉显示的布局的可见状态类区分上拉还是下拉,然后执行相应操作
public boolean isHeaderShown() {
return getHeaderLayout().isShown();
} public boolean isFooterShown() {
return getFooterLayout().isShown();
}

使用方法大概如下:

private boolean isRefreshing = false;//是否正在刷新的标志

private PullToRefreshListView news_list;//列表控件news_list

//设置上拉下拉事件
news_list.setOnRefreshListener(new OnRefreshListener<ListView>() { @Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
//在PullToRefresh的类库的com.handmark.pulltorefresh.library包下,打开PullToRefreshBase.java,在这个类的最后面添加代码。注意,需要重新添加library库。
//原理:根据下拉和上拉显示的布局的可见状态类区分上拉还是下拉,然后执行相应操作
if (!isRefreshing) { isRefreshing = true; if(refreshView.isHeaderShown()){
//下拉刷新 业务代码
refreshFirstPage();//刷新第一页数据
}else if(refreshView.isFooterShown()){
//上拉加载 业务代码
loadNextPage();//加载下一页内容
}
}else{
//一般来说我们会开另一个线程去获取数据,所以这儿会加上一个判断,如果已经在获取数据了,就onRefreshComplete(),就是将下拉收起;否则就去开新线程取数据,取完记得也要onRefreshComplete()哦
news_list.onRefreshComplete();
isRefreshing = false;
}
}
});

二:实现下拉刷新、下拉加载的图片个性化(图片居中)
参考资料:http://blog.csdn.net/superjunjin/article/details/45022595

定义刷新动画的layout

根据layout中的pull_to_refresh_header_vertical.xml文件修改成如下(图片居中,文字全部设置为gone。不占用空间)

<?xml version="1.0" encoding="utf-8"?>
<!-- (1)实现下拉刷新、下拉加载的动画个性化(图片居中) -->
<merge xmlns:android="http://schemas.android.com/apk/res/android" > <FrameLayout
android:id="@+id/fl_inner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/header_footer_top_bottom_padding"
android:paddingLeft="@dimen/header_footer_left_right_padding"
android:paddingRight="@dimen/header_footer_left_right_padding"
android:paddingTop="@dimen/header_footer_top_bottom_padding" > <FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" > <ImageView
android:id="@+id/pull_to_refresh_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" /> <ProgressBar
android:id="@+id/pull_to_refresh_progress"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"
android:visibility="gone" /> </FrameLayout> <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:orientation="vertical" > <TextView
android:id="@+id/pull_to_refresh_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearance"
android:textStyle="bold"
android:visibility="gone" /> <TextView
android:id="@+id/pull_to_refresh_sub_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:visibility="gone" />
</LinearLayout>
</FrameLayout> </merge>

pull_to_refresh_header_custom.xml

设置自定义动画效果

设置一个简单的京东小人走的动画效果,在drawable文件夹下新建一个xml

<?xml version="1.0" encoding="utf-8"?>
<!-- (2)实现下拉刷新、下拉加载的动画个性化(图片居中) -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/app_refresh_people_0" android:duration="100"></item>
<item android:drawable="@drawable/app_refresh_people_1" android:duration="100"></item>
<item android:drawable="@drawable/app_refresh_people_2" android:duration="100"></item>
<item android:drawable="@drawable/app_refresh_people_3" android:duration="100"></item> </animation-list>

jd_refreshlist.xml

新建刷新动画的layout,TweenAnimLoadingLayout,类似于之前的源码中的FlipLoadingLayout和RotateLoadingLayout

package com.handmark.pulltorefresh.library.internal;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View; import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
import com.handmark.pulltorefresh.library.R;
/**
* (3)实现下拉刷新、下拉加载的动画个性化(图片居中)*/
public class TweenAnimLoadingLayout extends LoadingLayout{ private AnimationDrawable animationDrawable;//创建动画序列对象 public TweenAnimLoadingLayout(Context context, Mode mode,
Orientation scrollDirection, TypedArray attrs) {
super(context, mode, scrollDirection, attrs);
// TODO Auto-generated constructor stub //初始化
mHeaderImage.setImageResource(R.drawable.jd_refreshlist);
animationDrawable = (AnimationDrawable) mHeaderImage.getDrawable(); } // 默认图片
protected int getDefaultDrawableResId() {
// TODO Auto-generated method stub
return R.drawable.app_refresh_people_0;
} @Override
protected void onLoadingDrawableSet(Drawable imageDrawable) { } @Override
protected void onPullImpl(float scaleOfLayout) {
// TODO Auto-generated method stub } // 下拉以刷新
protected void pullToRefreshImpl() {
// TODO Auto-generated method stub } // 正在刷新时回调
protected void refreshingImpl() {
// 播放帧动画
animationDrawable.start();
} // 释放以刷新
protected void releaseToRefreshImpl() {
// TODO Auto-generated method stub } // 重新设置
protected void resetImpl() {
mHeaderImage.setVisibility(View.VISIBLE);
mHeaderImage.clearAnimation(); } }

TweenAnimLoadingLayout

替换之前的布局文件,在LoadingLayout类的构造函数中修改引用的布局文件:

public LoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {
super(context);
mMode = mode;
mScrollDirection = scrollDirection; switch (scrollDirection) {
case HORIZONTAL:
LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal, this); break;
case VERTICAL:
default:
//LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical, this); /*(4)实现下拉刷新、下拉加载的动画个性化(图片居中)*/
LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_custom, this);
break;
}

LoadingLayout

替换之前的刷新layout为TweenAnimLoadingLayout

找到library项目com.handmark.pulltorefresh.library包下的PullToRefreshListView的createLoadingLayout进入,在createLoadingLayout方法中再进入createLoadingLayout,找到最原始的新建动画layout的地方,把默认的RotateLoadingLayout改成TweenAnimLoadingLayout就行了。在PullToRefreshBase类下:

LoadingLayout createLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
switch (this) {
case ROTATE:
default:
//return new RotateLoadingLayout(context, mode, scrollDirection, attrs);
/*(5)实现下拉刷新、下拉加载的动画个性化(图片居中)*/
return new TweenAnimLoadingLayout(context, mode, scrollDirection, attrs);
case FLIP:
return new FlipLoadingLayout(context, mode, scrollDirection, attrs);
}
}

PullToRefreshBase

三:实现下拉刷新、下拉加载的动画自定义

1、需要将项目中用到的动画文件和图片资源复制一份到library工程中。

2、主要修改RotateLoadingLayout文件

/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.handmark.pulltorefresh.library.internal; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Matrix;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView.ScaleType; import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
import com.handmark.pulltorefresh.library.R; public class RotateLoadingLayout extends LoadingLayout { static final int ROTATION_ANIMATION_DURATION = 1200; private final Animation mRotateAnimation;
private final Matrix mHeaderImageMatrix; private float mRotationPivotX, mRotationPivotY; private final boolean mRotateDrawableWhilePulling; /*(1)实现自定义加载动画*/
private boolean mUseIntrinsicAnimation;//标记传入的drawable是否是AnimationDrawable
private AnimationDrawable animationDrawable;//创建动画序列对象 public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
super(context, mode, scrollDirection, attrs); mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true); mHeaderImage.setScaleType(ScaleType.MATRIX);
mHeaderImageMatrix = new Matrix();
mHeaderImage.setImageMatrix(mHeaderImageMatrix); mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION);
mRotateAnimation.setRepeatCount(Animation.INFINITE);
mRotateAnimation.setRepeatMode(Animation.RESTART);
} public void onLoadingDrawableSet(Drawable imageDrawable) { /*(2)实现自定义加载动画*/
//如果传进来的是动画,那么
if(imageDrawable instanceof AnimationDrawable){ mUseIntrinsicAnimation = true;//设置标记值为true
mHeaderImage.setImageResource(R.drawable.jd_refreshlist);//给图标引用想用的动画(此处需要保证项目中用到的动画文件和图片资源复制一份到library中)
animationDrawable = (AnimationDrawable) imageDrawable;
}
else{
if (null != imageDrawable) {
mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f);
mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f);
}
} } protected void onPullImpl(float scaleOfLayout) {
/*(2)实现自定义加载动画*/
//如果传进来的是动画,那么
if(mUseIntrinsicAnimation){ }else{
float angle;
if (mRotateDrawableWhilePulling) {
angle = scaleOfLayout * 90f;
} else {
angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f));
} mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY);
mHeaderImage.setImageMatrix(mHeaderImageMatrix);
} } // 正在刷新时回调
protected void refreshingImpl() { /*(2)实现自定义加载动画*/
//如果传进来的是动画,那么
if(mUseIntrinsicAnimation){
animationDrawable.start();// 播放帧动画
}else{
mHeaderImage.startAnimation(mRotateAnimation);// 播放帧动画
} } // 重新设置
protected void resetImpl() {
/*(2)实现自定义加载动画*/
//如果传进来的是动画,那么
if(mUseIntrinsicAnimation){
mHeaderImage.setVisibility(View.VISIBLE);
mHeaderImage.clearAnimation();
}else{
mHeaderImage.clearAnimation();
resetImageRotation();
} } private void resetImageRotation() {
/*(2)实现自定义加载动画*/
//如果传进来的是动画,那么
if(mUseIntrinsicAnimation){ }else{
if (null != mHeaderImageMatrix) {
mHeaderImageMatrix.reset();
mHeaderImage.setImageMatrix(mHeaderImageMatrix);
}
} } // 下拉以刷新
protected void pullToRefreshImpl() {
// NO-OP
} // 释放以刷新
protected void releaseToRefreshImpl() {
// NO-OP
} // 默认图片
protected int getDefaultDrawableResId() {
/*(2)实现自定义加载动画*/
//如果传进来的是动画,那么
if(mUseIntrinsicAnimation){
return R.drawable.app_refresh_people_0;
}else{
return R.drawable.default_ptr_rotate;
} } }

RotateLoadingLayout

3、使用方法

//额外的设置:设置下拉刷新和上拉加载的图片和文字,背景颜色等
private void setPullToRefreshAttribute(){ ILoadingLayout startLabels = news_list.getLoadingLayoutProxy(true, false);
startLabels.setPullLabel("下拉刷新...");// 刚下拉时,显示的提示
startLabels.setReleaseLabel("松开刷新...");//下来达到一定距离时,显示的提示
startLabels.setRefreshingLabel("正在刷新...");// 刷新时 /*(3)实现自定义加载动画*/
//设置加载动画图标:方式一
AnimationDrawable jdAnimation = (AnimationDrawable) getResources().getDrawable(R.drawable.jd_refreshlist);
startLabels.setLoadingDrawable(jdAnimation); ILoadingLayout endLabels = news_list.getLoadingLayoutProxy(false, true);
endLabels.setPullLabel("上拉加载...");// 刚下拉时,显示的提示
endLabels.setReleaseLabel("松开加载...");//下来达到一定距离时,显示的提示
endLabels.setRefreshingLabel("正在加载...");// 刷新时
/*(3)实现自定义加载动画*/
//设置加载动画图标:方式二
Drawable drawable2 = (Drawable) getResources().getDrawable(R.drawable.progressbar1);
endLabels.setLoadingDrawable(drawable2);
}

PullToRefresh的个性化扩展的更多相关文章

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

    很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性.查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷 ...

  2. Markdown温故知新(4):更多扩展语法及HTML

    1.强调(删除 & 高亮) 2.脚注(注脚) 3.数学公式 4.更多扩展语法 5.终极扩展之内嵌 HTML 5.1.文本修饰类标签 5.2.内容排版类标签 5.3.图片及多媒体标签 5.4.锚 ...

  3. Visual Studio Code,完美的编辑器

    今日凌晨,微软的文本(代码)编辑器 Visual Studio Code(简称 VS Code),发布了首个正式版,距离首个 beta 版上线时间刚好一年. 在十多年的编程经历中,我使用过非常多的的代 ...

  4. Android 7.0 Nougat牛轧糖 发布啦

    Android 7.0 Nougat牛轧糖 发布啦 Android 7.0 Nougat 牛轧糖于本月发布了. 从官方blog里可以了解到这个版本的新特性. Android 7.0 从2016年8月正 ...

  5. 01 Apache Solr:提升检索体验 为什么是Solr

    背景:      最近开发一个大型的仓储管理平台项目,项目的前身是无数个版本的历史悠久的基于CS模式的Windows桌面程序.然后对于每一个客户,我们可能需要为之定制比较个性化的特殊功能.于是,有一个 ...

  6. C++仿函数和typename的用法

    1.仿函数的定义是很简单的,就是一个重载了括号()运算符的类,也被称为函数对象. 主要是用于个性化扩展算法对象.stl中实现了好多算法,每个算法都可以完成日常的大部分工作,设计者还允许你在这些强大的算 ...

  7. XAF-BI.Dashboard模块概述 web/win

    Dashboard模块介绍了在ASP.NET XAF 和 WinForms 应用程序中简单的集成 DevExpress Dashboard控件的方法. 其实不仅仅是控件,利用了现有的XAF数据模型,这 ...

  8. 分布式任务调度平台XXL-JOB

    <分布式任务调度平台XXL-JOB>       一.简介 1.1 概述 XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并 ...

  9. python面向对象编程 -- 封装、继承

    面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...

随机推荐

  1. 统计计算与R语言的资料汇总(截止2016年12月)

    本文在Creative Commons许可证下发布. 在fedora Linux上断断续续使用R语言过了9年后,发现R语言在国内用的人逐渐多了起来.由于工作原因,直到今年暑假一个赴京工作的机会与一位统 ...

  2. js特效第九天

    offset家族(获取元素尺寸) offsetWidth得到对象的宽度,自己的,与他人无关 offsetWidth = width+border+padding,不包含margin offsetHei ...

  3. viedeo

    http://download.farsight.com.cn/download/Android.htm

  4. 2014年国人开发的最热门的.NET开源项目 TOP 25

    原文地址:http://www.cnphp6.com/archives/72213 1 奎宇工作室 / DotNetCodes C# 一些常用的功能性代码,可以减少许多开发时间,而且类与类之间没有什么 ...

  5. 零基础学习hadoop到上手工作线路指导

    零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...

  6. CSS3之边框图片border-image

    CSS3中有关border的属性,还有很多,今天我将为大家介绍一个很好玩的属性——Border-image.有了CSS3之边框图片Border-image,我们可以轻松搞定圆角,轻松搞定很多之前难搞的 ...

  7. 5-17 Hashing (25分)

    The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...

  8. ajax 返回json数据操作

    例子: $.ajax({ url: "<?=Url::toRoute('add-all-staff')?>", type: 'get', dataType: 'json ...

  9. 【Away3D代码解读】(四):主要模块简介

    数据模块: Away3D中最核心的数据类是Mesh类,我们先看看Mesh类的继承关系: NamedAssetBase:为对象提供id和name属性,是Away3D大部分类的基类: Object3D:3 ...

  10. Linux使用netstat命令查看并发连接数[转]

    转自:http://www.cnblogs.com/wayne173/p/5652043.html Linux使用netstat命令查看并发连接数   我们的网站部署在linux的服务器上,特别是we ...