PullToRefresh的个性化扩展
一:实现区别下拉刷新和上拉加载
参考资料: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的个性化扩展的更多相关文章
- Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向
很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性.查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷 ...
- Markdown温故知新(4):更多扩展语法及HTML
1.强调(删除 & 高亮) 2.脚注(注脚) 3.数学公式 4.更多扩展语法 5.终极扩展之内嵌 HTML 5.1.文本修饰类标签 5.2.内容排版类标签 5.3.图片及多媒体标签 5.4.锚 ...
- Visual Studio Code,完美的编辑器
今日凌晨,微软的文本(代码)编辑器 Visual Studio Code(简称 VS Code),发布了首个正式版,距离首个 beta 版上线时间刚好一年. 在十多年的编程经历中,我使用过非常多的的代 ...
- Android 7.0 Nougat牛轧糖 发布啦
Android 7.0 Nougat牛轧糖 发布啦 Android 7.0 Nougat 牛轧糖于本月发布了. 从官方blog里可以了解到这个版本的新特性. Android 7.0 从2016年8月正 ...
- 01 Apache Solr:提升检索体验 为什么是Solr
背景: 最近开发一个大型的仓储管理平台项目,项目的前身是无数个版本的历史悠久的基于CS模式的Windows桌面程序.然后对于每一个客户,我们可能需要为之定制比较个性化的特殊功能.于是,有一个 ...
- C++仿函数和typename的用法
1.仿函数的定义是很简单的,就是一个重载了括号()运算符的类,也被称为函数对象. 主要是用于个性化扩展算法对象.stl中实现了好多算法,每个算法都可以完成日常的大部分工作,设计者还允许你在这些强大的算 ...
- XAF-BI.Dashboard模块概述 web/win
Dashboard模块介绍了在ASP.NET XAF 和 WinForms 应用程序中简单的集成 DevExpress Dashboard控件的方法. 其实不仅仅是控件,利用了现有的XAF数据模型,这 ...
- 分布式任务调度平台XXL-JOB
<分布式任务调度平台XXL-JOB> 一.简介 1.1 概述 XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并 ...
- python面向对象编程 -- 封装、继承
面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...
随机推荐
- 将Magento后台汉化的方法
方法一: 打开/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php文件, 找到几个用来显示的代码,替换成 ...
- IComparer接口与
IComparable比较接口,继承此接口可对lis<T>调用sort进行排序 或者调用sort时可以为sort方法提供继承了IComparer的比较器
- Java文件分割
package FileDemo; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStre ...
- Objective-C Runtime 运行时之二:成员变量与属性
类型编码(Type Encoding) 作为对Runtime的补充,编译器将每个方法的返回值和参数类型编码为一个字符串,并将其与方法的selector关联在一起.这种编码方案在其它情况下也是非常有用的 ...
- UITextView详解
self.textView = [[[UITextView alloc] initWithFrame:self.view.frame] autorelease]; //初始化大小并自动释放 sel ...
- [二]JQueryMobile常用的组件介绍
1.页头.主要部门.页尾构成一个基本的页面 2.按钮组件(input.a) 3.列表组件(ul) 4.表格组件(table)
- php如何清除html格式并去除文字中的空格然后截取文字
PHP如何清除html格式并去除文字中的空格然后截取文字,详细分享一下处理方法(顺便对PHP清除HTML字符串的函数做了一个小结): htmlspecialchars 将特殊字元转成 HTML格式语法 ...
- Arrays 类操作 Java 的数组排序
使用 Arrays 类操作 Java 中的数组 Arrays 类是 Java 中提供的一个工具类,在 java.util 包中.该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序.搜索等( ...
- 我眼中的PM
我眼中的PM 1 我眼中的PM 1.1 人云“一个管理,半个专家”,我说“一个管理,两个专家” 如今,我发现我们不得不面对这样一个现实——角色兼职.我习惯上把项目分为三类:性命攸关的项目(涉及到人身安 ...
- CentOS 下SSH无密码登录的配置
CentOS 下SSH无密码登录的配置 最近学习Hadoop.它要求各节点之间通过SSH无密码登录,配置SSH的时候费了一番功夫,记录下来,以备忘. 配置SSH无密码登录需要3步: 1.生成公钥和私钥 ...