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

参考资料: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. VBScript Sample:遍历文件夹并获取XML文件中指定内容

    案例: 我有一个文件夹,里面有很多子文件夹,每个子文件夹中都存在一个相同名字的XML文件,XML文件里面的标签结构相同,只是内容不同,XML文件中包含ID,Name等标签. 文件夹及文件结构如下图: ...

  2. Bzoj 4403: 序列统计 Lucas定理,组合数学,数论

    4403: 序列统计 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 328  Solved: 162[Submit][Status][Discuss] ...

  3. Bzoj 4591: [Shoi2015]超能粒子炮·改 数论,Lucas定理,排列组合

    4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 178  Solved: 70[Submit][Stat ...

  4. Extjs4 MVC Controlller中refs使用

    前面几篇写了一下mvc的整体使用方法,今天写一下controller中refs的试用,refs的作用类似于我们告诉controller我们的一个元素的别名,既alias,那么controller就会为 ...

  5. Morris Traversal

    昨天临近要睡觉的时候做了一个leetcode题目,"Recover BST",算法很容易就想到了,直接找出两个异常点就好了,但是我写的算法是用栈实现的非递归遍历,空间复杂度是O(N ...

  6. Delphi给窗体镶边-为控件加边框,描边,改变边框颜色

    PS:因为我现在用的电脑是WIN7 64位系统,所以没有实现功能,不知道XP是否可行. //1.定义方法 procedure WMNCPaint(var Msg : TWMNCPaint); mess ...

  7. nyoj 218 Dinner

    Dinner 时间限制:100 ms  |  内存限制:65535 KB 难度:1   描述 Little A is one member of ACM team. He had just won t ...

  8. Linux Pmap 命令:查看进程用了多少内存

    Pmap 提供了进程的内存映射,pmap命令用于显示一个或多个进程的内存状态.其报告进程的地址空间和内存状态信息.Pmap实际上是一个Sun OS上的命令,linux仅支持其有限的功能.但是它还是对查 ...

  9. MongoDB让人恶心的配置

    dbpath.logpath必须指定到硬盘的根目录: dbpath=D:\data\dblogpath=D:\data\log\Mongodb.log 不然启动时会报没有设置dbpath的错误

  10. Clarkson不等式