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 封装 封装:将数据和操作组装到一起,对外 ...
随机推荐
- wxWidgets Tutorial
wxWidgets Tutorial网站整理 两个重要的教程网站:1:点这里:2:点这里. 还有一个wxWidgets项目参考的网站:点这里. 已经翻译好的中文教程:点这里. 参考书籍:<wxW ...
- Python几个算法实现
1.平衡点问题: 比如int[] numbers = {1,3,5,7,8,25,4,20}; 25前面的总和为24,25后面的总和也是24,25这个点就是平衡点:假如一个数组中的元素,其前面的部分等 ...
- HW6.29
public class Solution { public static void main(String[] args) { int count = 0; int[] card = new int ...
- uCos 之 TaskIdle() 注意事项【worldsing笔记】
在大多OS里都存在Idle线程或任务,同样uCos也不例外,为什么估计很少有人细研究.为什么设立Idle? 能不能去了? 首先看看uCos中关于Idle的代码做个介绍: config.h里对Idle的 ...
- C#中反射的使用(How to use reflect in CSharp)(1)
最近想做一个插件式的软件给公司的监控用,初步的想法是使用C#去反射Dll,Invoke其中的方法.此文仅供开发参考,不涉及原理,98%的代码以及2%的废话. 测试Solution是这么建的(.NET ...
- 【Cocos2d-X开发学习笔记】第09期:渲染框架之菜单类(CCMenu)的使用
本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 一.菜单项(CCMenuItem) 菜单项 ...
- .NET加密配置文件connectionStrings节点
具体的可以参考petshop源码程序. 加密前: <connectionStrings> <add name="SQLProfileConnString" con ...
- postfix反垃圾邮件说明
参考地址:http://guailele.blog.51cto.com/1156442/780223 1.打开 smtp 的认证模块 在/etc/postfix/main.cf文件最后加上: sm ...
- VS项目如何运用svn的忽略列表
在实际的项目开发中,有些文件(比如bin,obj下的文件)是不需要放在svn里面的,因为每次都会重新生成. 该如何排除这些文件那? 我试着在svn server上删除了这些文件夹,但是在文件夹上还是显 ...
- Files to be needed by importing the android application with eclipse
1. AndroidManifest.xml 2. project.properties # This file is automatically generated by Android Tools ...