您的位置:首页 > 移动开发 > Android开发

android下拉刷新和上拉加载更多的框架pulltoreflesh

2015-08-11 09:58 246 查看
1,http://blog.csdn.net/lmj623565791/article/details/38238749

2,修改pulltorefresh刷新动画效果

Android UI- PullToRrefresh自定义下拉刷新动画

如果觉得本文不错,麻烦投一票,2014年博客之星投票地址:http://vote.blog.csdn.net/blogstar2014/details?username=wwj_748#content

本篇博文要给大家分享的是如何使用修改开源项目PullToRrefresh下拉刷新的动画,来满足我们开发当中特定的需求,我们比较常见的一种下拉刷新样式可能是以下这种:



就是下拉列表的时候两个箭头上下翻转,更改日期文本和刷新状态,这种是最普遍的一种模式。

另外一种是旋转动画,就是刷新的时候一个圈不停的旋转,类似南方周末阅读器(注:是小巫公司的一个产品,各位多多支持O(∩_∩)O):






github地址:https://github.com/devilWwj/Android-PullToRefresh

下载下来之后,import到工作空间,导入到目标项目中去,不清楚如何导入关联项目的童鞋请自行百度。

我这里要实现的一种效果是下拉刷新时播放一个帧动画

增加动画列表:

[html] view
plaincopy





<?xml version="1.0" encoding="utf-8"?>

<!--

根标签为animation-list,其中oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画

根标签下,通过item标签对动画中的每一个图片进行声明

android:duration 表示展示所用的该图片的时间长度

-->

<animation-list

xmlns:android="http://schemas.android.com/apk/res/android"

android:oneshot="false"

>

<item android:drawable="@drawable/loading1" android:duration="150"></item>

<item android:drawable="@drawable/loading2" android:duration="150"></item>

<item android:drawable="@drawable/loading3" android:duration="150"></item>

<item android:drawable="@drawable/loading4" android:duration="150"></item>

</animation-list>

修改下拉刷新布局:

/PullToRefresh/res/layout/pull_to_refresh_header_simple.xml

[java] view
plaincopy





<?xml version="1.0" encoding="utf-8"?>

<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_horizontal" >



<ImageView

android:id="@+id/pull_to_refresh_image"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:src="@drawable/loading1"

/>



</FrameLayout>



</FrameLayout>



</merge>

增加自定义的加载布局

/PullToRefresh/src/com/handmark/pulltorefresh/library/internal/TweenAnimLoadingLayout.java

[java] view
plaincopy





package com.handmark.pulltorefresh.library.internal;



import com.handmark.pulltorefresh.library.R;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;



import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.Drawable;

import android.view.View;



/**

* @date 2015/1/8

* @author wuwenjie

* @desc 帧动画加载布局

*/

public class TweenAnimLoadingLayout extends LoadingLayout {



private AnimationDrawable animationDrawable;



public TweenAnimLoadingLayout(Context context, Mode mode,

Orientation scrollDirection, TypedArray attrs) {

super(context, mode, scrollDirection, attrs);

// 初始化

mHeaderImage.setImageResource(R.drawable.refresh_anim);

animationDrawable = (AnimationDrawable) mHeaderImage.getDrawable();

}

// 默认图片

@Override

protected int getDefaultDrawableResId() {

return R.drawable.loading1;

}



@Override

protected void onLoadingDrawableSet(Drawable imageDrawable) {

// NO-OP

}



@Override

protected void onPullImpl(float scaleOfLayout) {

// NO-OP

}

// 下拉以刷新

@Override

protected void pullToRefreshImpl() {

// NO-OP

}

// 正在刷新时回调

@Override

protected void refreshingImpl() {

// 播放帧动画

animationDrawable.start();

}

// 释放以刷新

@Override

protected void releaseToRefreshImpl() {

// NO-OP

}

// 重新设置

@Override

protected void resetImpl() {

mHeaderImage.setVisibility(View.VISIBLE);

mHeaderImage.clearAnimation();

}



}

我们只要修改开源项目中的LodingLayout代码:

/PullToRefresh/src/com/handmark/pulltorefresh/library/internal/LoadingLayout.java

[java] view
plaincopy





/*******************************************************************************

* 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.annotation.SuppressLint;

import android.content.Context;

import android.content.res.ColorStateList;

import android.content.res.TypedArray;

import android.graphics.Typeface;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.Drawable;

import android.text.TextUtils;

import android.util.TypedValue;

import android.view.Gravity;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.view.animation.Interpolator;

import android.view.animation.LinearInterpolator;

import android.widget.FrameLayout;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.ProgressBar;

import android.widget.TextView;



import com.handmark.pulltorefresh.library.ILoadingLayout;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;

import com.handmark.pulltorefresh.library.R;



@SuppressLint("ViewConstructor")

public abstract class LoadingLayout extends FrameLayout implements ILoadingLayout {



static final String LOG_TAG = "PullToRefresh-LoadingLayout";



static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();



private FrameLayout mInnerLayout;



protected final ImageView mHeaderImage;

protected final ProgressBar mHeaderProgress;



private boolean mUseIntrinsicAnimation;



private final TextView mHeaderText;

private final TextView mSubHeaderText;



protected final Mode mMode;

protected final Orientation mScrollDirection;



private CharSequence mPullLabel;

private CharSequence mRefreshingLabel;

private CharSequence mReleaseLabel;





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);

// 修改代码

LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_simple, this);

break;

}



mInnerLayout = (FrameLayout) findViewById(R.id.fl_inner);

mHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_text);

mHeaderProgress = (ProgressBar) mInnerLayout.findViewById(R.id.pull_to_refresh_progress);

mSubHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_sub_text);

mHeaderImage = (ImageView) mInnerLayout.findViewById(R.id.pull_to_refresh_image);





FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInnerLayout.getLayoutParams();



switch (mode) {

case PULL_FROM_END:

lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.TOP : Gravity.LEFT;



// Load in labels

mPullLabel = context.getString(R.string.pull_to_refresh_from_bottom_pull_label);

mRefreshingLabel = context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label);

mReleaseLabel = context.getString(R.string.pull_to_refresh_from_bottom_release_label);

break;



case PULL_FROM_START:

default:

lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.BOTTOM : Gravity.RIGHT;



// Load in labels

mPullLabel = context.getString(R.string.pull_to_refresh_pull_label);

mRefreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label);

mReleaseLabel = context.getString(R.string.pull_to_refresh_release_label);

break;

}



if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) {

Drawable background = attrs.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground);

if (null != background) {

ViewCompat.setBackground(this, background);

}

}



// if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance)) {

// TypedValue styleID = new TypedValue();

// attrs.getValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance, styleID);

// setTextAppearance(styleID.data);

// }

// if (attrs.hasValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance)) {

// TypedValue styleID = new TypedValue();

// attrs.getValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance, styleID);

// setSubTextAppearance(styleID.data);

// }

//

// // Text Color attrs need to be set after TextAppearance attrs

// if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextColor)) {

// ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderTextColor);

// if (null != colors) {

// setTextColor(colors);

// }

// }

// if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderSubTextColor)) {

// ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderSubTextColor);

// if (null != colors) {

// setSubTextColor(colors);

// }

// }



// Try and get defined drawable from Attrs

Drawable imageDrawable = null;

if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawable)) {

imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawable);

}



// Check Specific Drawable from Attrs, these overrite the generic

// drawable attr above

switch (mode) {

case PULL_FROM_START:

default:

if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableStart)) {

imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableStart);

} else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableTop)) {

Utils.warnDeprecation("ptrDrawableTop", "ptrDrawableStart");

imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop);

}

break;



case PULL_FROM_END:

if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableEnd)) {

imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableEnd);

} else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableBottom)) {

Utils.warnDeprecation("ptrDrawableBottom", "ptrDrawableEnd");

imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableBottom);

}

break;

}



// If we don't have a user defined drawable, load the default

if (null == imageDrawable) {

imageDrawable = context.getResources().getDrawable(getDefaultDrawableResId());

}



// Set Drawable, and save width/height

setLoadingDrawable(imageDrawable);



reset();

}



public final void setHeight(int height) {

ViewGroup.LayoutParams lp = getLayoutParams();

lp.height = height;

requestLayout();

}



public final void setWidth(int width) {

ViewGroup.LayoutParams lp = getLayoutParams();

lp.width = width;

requestLayout();

}



public final int getContentSize() {

switch (mScrollDirection) {

case HORIZONTAL:

return mInnerLayout.getWidth();

case VERTICAL:

default:

return mInnerLayout.getHeight();

}

}



public final void hideAllViews() {

// if (View.VISIBLE == mHeaderText.getVisibility()) {

// mHeaderText.setVisibility(View.INVISIBLE);

// }

// if (View.VISIBLE == mHeaderProgress.getVisibility()) {

// mHeaderProgress.setVisibility(View.INVISIBLE);

// }

// if (View.VISIBLE == mHeaderImage.getVisibility()) {

// mHeaderImage.setVisibility(View.INVISIBLE);

// }

// if (View.VISIBLE == mSubHeaderText.getVisibility()) {

// mSubHeaderText.setVisibility(View.INVISIBLE);

// }

}



public final void onPull(float scaleOfLayout) {

if (!mUseIntrinsicAnimation) {

onPullImpl(scaleOfLayout);

}

}



public final void pullToRefresh() {

// if (null != mHeaderText) {

// mHeaderText.setText(mPullLabel);

// }



// Now call the callback

pullToRefreshImpl();

}



public final void refreshing() {

if (null != mHeaderText) {

mHeaderText.setText(mRefreshingLabel);

}



if (mUseIntrinsicAnimation) {

((AnimationDrawable) mHeaderImage.getDrawable()).start();

} else {

// Now call the callback

refreshingImpl();

}



// if (null != mSubHeaderText) {

// mSubHeaderText.setVisibility(View.GONE);

// }

}



public final void releaseToRefresh() {

// if (null != mHeaderText) {

// mHeaderText.setText(mReleaseLabel);

// }



// Now call the callback

releaseToRefreshImpl();

}



public final void reset() {

// if (null != mHeaderText) {

// mHeaderText.setText(mPullLabel);

// }

mHeaderImage.setVisibility(View.VISIBLE);



if (mUseIntrinsicAnimation) {

((AnimationDrawable) mHeaderImage.getDrawable()).stop();

} else {

// Now call the callback

resetImpl();

}



// if (null != mSubHeaderText) {

// if (TextUtils.isEmpty(mSubHeaderText.getText())) {

// mSubHeaderText.setVisibility(View.GONE);

// } else {

// mSubHeaderText.setVisibility(View.VISIBLE);

// }

// }

}



@Override

public void setLastUpdatedLabel(CharSequence label) {

// setSubHeaderText(label);

}



@Override

public final void setLoadingDrawable(Drawable imageDrawable) {

// Set Drawable

mHeaderImage.setImageDrawable(imageDrawable);

mUseIntrinsicAnimation = (imageDrawable instanceof AnimationDrawable);



// Now call the callback

onLoadingDrawableSet(imageDrawable);

}



@Override

public void setPullLabel(CharSequence pullLabel) {

mPullLabel = pullLabel;

}



@Override

public void setRefreshingLabel(CharSequence refreshingLabel) {

mRefreshingLabel = refreshingLabel;

}



@Override

public void setReleaseLabel(CharSequence releaseLabel) {

mReleaseLabel = releaseLabel;

}



@Override

public void setTextTypeface(Typeface tf) {

mHeaderText.setTypeface(tf);

}



public final void showInvisibleViews() {

// if (View.INVISIBLE == mHeaderText.getVisibility()) {

// mHeaderText.setVisibility(View.VISIBLE);

// }

// if (View.INVISIBLE == mHeaderProgress.getVisibility()) {

// mHeaderProgress.setVisibility(View.VISIBLE);

// }

if (View.INVISIBLE == mHeaderImage.getVisibility()) {

mHeaderImage.setVisibility(View.VISIBLE);

}

// if (View.INVISIBLE == mSubHeaderText.getVisibility()) {

// mSubHeaderText.setVisibility(View.VISIBLE);

// }

}



/**

* Callbacks for derivative Layouts

*/



protected abstract int getDefaultDrawableResId();



protected abstract void onLoadingDrawableSet(Drawable imageDrawable);



protected abstract void onPullImpl(float scaleOfLayout);



protected abstract void pullToRefreshImpl();



protected abstract void refreshingImpl();



protected abstract void releaseToRefreshImpl();



protected abstract void resetImpl();



private void setSubHeaderText(CharSequence label) {

if (null != mSubHeaderText) {

if (TextUtils.isEmpty(label)) {

mSubHeaderText.setVisibility(View.GONE);

} else {

mSubHeaderText.setText(label);



// Only set it to Visible if we're GONE, otherwise VISIBLE will

// be set soon

if (View.GONE == mSubHeaderText.getVisibility()) {

mSubHeaderText.setVisibility(View.VISIBLE);

}

}

}

}



private void setSubTextAppearance(int value) {

if (null != mSubHeaderText) {

mSubHeaderText.setTextAppearance(getContext(), value);

}

}



private void setSubTextColor(ColorStateList color) {

if (null != mSubHeaderText) {

mSubHeaderText.setTextColor(color);

}

}



private void setTextAppearance(int value) {

if (null != mHeaderText) {

mHeaderText.setTextAppearance(getContext(), value);

}

if (null != mSubHeaderText) {

mSubHeaderText.setTextAppearance(getContext(), value);

}

}



private void setTextColor(ColorStateList color) {

if (null != mHeaderText) {

mHeaderText.setTextColor(color);

}

if (null != mSubHeaderText) {

mSubHeaderText.setTextColor(color);

}

}



}

最后就不要让我提供源码了,笔者这里只是提供一个思路,把刷新的头布局更改为我们的自定义布局就行了。

最终效果是下拉刷新的时候会有一个不停在闪的灯,这里没有录制gif动画,只提供一张截图吧:



==============================================================================

效果预览:



xml布局

[html] view
plaincopyprint?

<com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:ptr="http://schemas.android.com/apk/res-auto"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:divider="#00000000"

android:cacheColorHint="#00000000"

android:listSelector="#00000000"

android:fastScrollEnabled="true"

ptr:ptrHeaderTextColor="@color/gray"

<span style="color:#ff0000;">ptr:ptrAnimationStyle="louisAnimationStyle"</span>

/>

lib底层配置

里面配置了自定义的动画样式











其他就照着这个库的正常用法使用就行

gif图片分离器:http://download.csdn.net/detail/richiezhu/9026175
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: