Android UI PullToRrefresh自定义下拉刷新动画 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

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

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

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

   

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

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

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

   

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

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

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

    增加动画列表:

<?xml version="1.0" encoding="utf-8"?><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>

    修改下拉刷新布局:

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

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

电脑资料

Android UI PullToRrefresh自定义下拉刷新动画》(https://www.unjs.com)。

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

   

最新文章