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

参考资料: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. 如何实现CSS居中?–CSS居中常用方法

    来源:http://www.ido321.com/824.html 一.水平居中 1.内联元素居中:相对父级块级元素居中对齐 1: .center-children { 2: text-align: ...

  2. ./wls1036_linux32.bin: /lib/ld-linux.so.2: bad ELF interpreter

    [CentOS]安装软件:/lib/ld-linux.so.2: bad ELF interpreter解决   环境: [orangle@localhost Downloads]$ uname -m ...

  3. android中setOnClickListener的那点事

    最近在写代码中,发现在xml文件设置了android:clickable="false",之后这个View还是可点的. 后来发现,是代码中对View设置了监听事件(setOnCli ...

  4. Memcached使用笔记

    1.linux启动memcached命令 进入到memcached安装目录,可以用whereis memcached查看,默认安装在/usr/bin/目录下 输入以下命令,下面两行任选一行就可以了 m ...

  5. 最简单的计算MD5方法

    原来写过一个计算MD5的程序,是用了一个叫MD5.pas的单元,使用起来还算简单,但还有更简单的办法,安装了indy就会有IdHashMessageDigest单元(delphi 7默认安装indy) ...

  6. A Tour of Go Function values

    Functions are values too. 在函数式语言中中函数都是变量,比如在javascript中 package main import ( "fmt" " ...

  7. ECSHOP 数据库结构说明 (适用版本v2.7.3)

    ECSHOP 数据库结构说明 (适用版本v2.7.3) 1.account_log 用户账目日志表 字段 类型 Null/默认 注释 log_id mediumint(8) 否 / 自增 ID 号 u ...

  8. IntelliJ IDEA 使用教程 - AS3篇

    喜欢IntelliJ IDEA的黑色皮肤,所以研究了下这个IDE的使用: 安装ActionScript Profiler插件: IDEA默认不带分析功能,需要下载安装该插件才行: File->S ...

  9. IDF实验室-简单编程-特殊的日子 writeup

    题目:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=50 题目提示要爆破,代表加密应该是不可逆的. 密文:4D ...

  10. ABAP DEBUG

    [Function] Command=/H Type=SystemCommand 将上面的文件推动到SAP 窗口 可以启动调试 ------------------------------------ ...