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

Android 中PullToRefresh 自定义下拉刷新动画

2016-10-10 16:42 197 查看
github地址:https://github.com/devilWwj/Android-PullToRefresh

studio 开发导入到自己的工程中去

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

增加动画列表:

<?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

<?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

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

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

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

}

}

}

还需进行以下:

更改LoadingLayout源码第78行,默认加载自定义布局;

②自定义LoadingLayout的子类,覆盖父类中的抽象方法;

③PullToRefreshBase源码第1328行createLoadingLayout方法中,默认返回自定义的LoadingLayout子类;

有一个问题,不知道为什么上下动画都改了,我只想改上边啊!!(自用)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: