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


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


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

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

增加动画列表:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--   
  3.     根标签为animation-list,其中oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画  
  4.     根标签下,通过item标签对动画中的每一个图片进行声明  
  5.     android:duration 表示展示所用的该图片的时间长度  
  6.  -->  
  7. <animation-list  
  8.   xmlns:android="http://schemas.android.com/apk/res/android"  
  9.   android:oneshot="false"  
  10.   >  
  11.     <item android:drawable="@drawable/loading1" android:duration="150"></item>  
  12.     <item android:drawable="@drawable/loading2" android:duration="150"></item>  
  13.     <item android:drawable="@drawable/loading3" android:duration="150"></item>  
  14.     <item android:drawable="@drawable/loading4" android:duration="150"></item>  
  15. </animation-list>
修改下拉刷新布局:

/PullToRefresh/res/layout/pull_to_refresh_header_simple.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <merge xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.   
  4.     <FrameLayout  
  5.         android:id="@+id/fl_inner"  
  6.         android:layout_width="fill_parent"  
  7.         android:layout_height="wrap_content"  
  8.         android:paddingBottom="@dimen/header_footer_top_bottom_padding"  
  9.         android:paddingLeft="@dimen/header_footer_left_right_padding"  
  10.         android:paddingRight="@dimen/header_footer_left_right_padding"  
  11.         android:paddingTop="@dimen/header_footer_top_bottom_padding" >  
  12.   
  13.         <FrameLayout  
  14.             android:layout_width="wrap_content"  
  15.             android:layout_height="wrap_content"  
  16.             android:layout_gravity="center_horizontal" >  
  17.   
  18.             <ImageView  
  19.                 android:id="@+id/pull_to_refresh_image"  
  20.                 android:layout_width="wrap_content"  
  21.                 android:layout_height="wrap_content"  
  22.                 android:layout_gravity="center"  
  23.                 android:src="@drawable/loading1"  
  24.                  />  
  25.   
  26.         </FrameLayout>  
  27.   
  28.     </FrameLayout>  
  29.   
  30. </merge>  

增加自定义的加载布局

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

  1. package com.handmark.pulltorefresh.library.internal;  
  2.   
  3. import com.handmark.pulltorefresh.library.R;  
  4. import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;  
  5. import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;  
  6.   
  7. import android.content.Context;  
  8. import android.content.res.TypedArray;  
  9. import android.graphics.drawable.AnimationDrawable;  
  10. import android.graphics.drawable.Drawable;  
  11. import android.view.View;  
  12.   
  13. /** 
  14.  * @date 2015/1/8 
  15.  * @author wuwenjie 
  16.  * @desc 帧动画加载布局 
  17.  */  
  18. public class TweenAnimLoadingLayout extends LoadingLayout {  
  19.   
  20.     private AnimationDrawable animationDrawable;  
  21.   
  22.     public TweenAnimLoadingLayout(Context context, Mode mode,  
  23.             Orientation scrollDirection, TypedArray attrs) {  
  24.         super(context, mode, scrollDirection, attrs);  
  25.         // 初始化  
  26.         mHeaderImage.setImageResource(R.drawable.refresh_anim);  
  27.         animationDrawable = (AnimationDrawable) mHeaderImage.getDrawable();  
  28.     }  
  29.     // 默认图片  
  30.     @Override  
  31.     protected int getDefaultDrawableResId() {  
  32.         return R.drawable.loading1;  
  33.     }  
  34.       
  35.     @Override  
  36.     protected void onLoadingDrawableSet(Drawable imageDrawable) {  
  37.         // NO-OP  
  38.     }  
  39.       
  40.     @Override  
  41.     protected void onPullImpl(float scaleOfLayout) {  
  42.         // NO-OP  
  43.     }  
  44.     // 下拉以刷新  
  45.     @Override  
  46.     protected void pullToRefreshImpl() {  
  47.         // NO-OP  
  48.     }  
  49.     // 正在刷新时回调  
  50.     @Override  
  51.     protected void refreshingImpl() {  
  52.         // 播放帧动画  
  53.         animationDrawable.start();  
  54.     }  
  55.     // 释放以刷新  
  56.     @Override  
  57.     protected void releaseToRefreshImpl() {  
  58.         // NO-OP  
  59.     }  
  60.     // 重新设置  
  61.     @Override  
  62.     protected void resetImpl() {  
  63.         mHeaderImage.setVisibility(View.VISIBLE);  
  64.         mHeaderImage.clearAnimation();  
  65.     }  
  66.   
  67. }  
   

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

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


  1. /******************************************************************************* 
  2.  * Copyright 2011, 2012 Chris Banes. 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  *******************************************************************************/  
  16. package com.handmark.pulltorefresh.library.internal;  
  17.   
  18. import android.annotation.SuppressLint;  
  19. import android.content.Context;  
  20. import android.content.res.ColorStateList;  
  21. import android.content.res.TypedArray;  
  22. import android.graphics.Typeface;  
  23. import android.graphics.drawable.AnimationDrawable;  
  24. import android.graphics.drawable.Drawable;  
  25. import android.text.TextUtils;  
  26. import android.util.TypedValue;  
  27. import android.view.Gravity;  
  28. import android.view.LayoutInflater;  
  29. import android.view.View;  
  30. import android.view.ViewGroup;  
  31. import android.view.animation.Interpolator;  
  32. import android.view.animation.LinearInterpolator;  
  33. import android.widget.FrameLayout;  
  34. import android.widget.ImageView;  
  35. import android.widget.LinearLayout;  
  36. import android.widget.ProgressBar;  
  37. import android.widget.TextView;  
  38.   
  39. import com.handmark.pulltorefresh.library.ILoadingLayout;  
  40. import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;  
  41. import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;  
  42. import com.handmark.pulltorefresh.library.R;  
  43.   
  44. @SuppressLint("ViewConstructor")  
  45. public abstract class LoadingLayout extends FrameLayout implements ILoadingLayout {  
  46.   
  47.     static final String LOG_TAG = "PullToRefresh-LoadingLayout";  
  48.   
  49.     static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();  
  50.   
  51.     private FrameLayout mInnerLayout;  
  52.   
  53.     protected final ImageView mHeaderImage;  
  54.     protected final ProgressBar mHeaderProgress;  
  55.   
  56.     private boolean mUseIntrinsicAnimation;  
  57.   
  58.     private final TextView mHeaderText;  
  59.     private final TextView mSubHeaderText;  
  60.   
  61.     protected final Mode mMode;  
  62.     protected final Orientation mScrollDirection;  
  63.   
  64.     private CharSequence mPullLabel;  
  65.     private CharSequence mRefreshingLabel;  
  66.     private CharSequence mReleaseLabel;  
  67.       
  68.   
  69.     public LoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {  
  70.         super(context);  
  71.         mMode = mode;  
  72.         mScrollDirection = scrollDirection;  
  73.   
  74.         switch (scrollDirection) {  
  75.             case HORIZONTAL:  
  76.                 LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal, this);  
  77.                 break;  
  78.             case VERTICAL:  
  79.             default:  
  80. //              LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical, this);  
  81.                 // 修改代码  
  82.                 LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_simple, this);   
  83.                 break;  
  84.         }  
  85.   
  86.         mInnerLayout = (FrameLayout) findViewById(R.id.fl_inner);  
  87.         mHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_text);  
  88.         mHeaderProgress = (ProgressBar) mInnerLayout.findViewById(R.id.pull_to_refresh_progress);  
  89.         mSubHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_sub_text);  
  90.         mHeaderImage = (ImageView) mInnerLayout.findViewById(R.id.pull_to_refresh_image);  
  91.           
  92.   
  93.         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInnerLayout.getLayoutParams();  
  94.   
  95.         switch (mode) {  
  96.             case PULL_FROM_END:  
  97.                 lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.TOP : Gravity.LEFT;  
  98.   
  99.                 // Load in labels  
  100.                 mPullLabel = context.getString(R.string.pull_to_refresh_from_bottom_pull_label);  
  101.                 mRefreshingLabel = context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label);  
  102.                 mReleaseLabel = context.getString(R.string.pull_to_refresh_from_bottom_release_label);  
  103.                 break;  
  104.   
  105.             case PULL_FROM_START:  
  106.             default:  
  107.                 lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.BOTTOM : Gravity.RIGHT;  
  108.   
  109.                 // Load in labels  
  110.                 mPullLabel = context.getString(R.string.pull_to_refresh_pull_label);  
  111.                 mRefreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label);  
  112.                 mReleaseLabel = context.getString(R.string.pull_to_refresh_release_label);  
  113.                 break;  
  114.         }  
  115.   
  116.         if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) {  
  117.             Drawable background = attrs.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground);  
  118.             if (null != background) {  
  119.                 ViewCompat.setBackground(this, background);  
  120.             }  
  121.         }  
  122.   
  123. //      if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance)) {  
  124. //          TypedValue styleID = new TypedValue();  
  125. //          attrs.getValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance, styleID);  
  126. //          setTextAppearance(styleID.data);  
  127. //      }  
  128. //      if (attrs.hasValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance)) {  
  129. //          TypedValue styleID = new TypedValue();  
  130. //          attrs.getValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance, styleID);  
  131. //          setSubTextAppearance(styleID.data);  
  132. //      }  
  133. //  
  134. //      // Text Color attrs need to be set after TextAppearance attrs  
  135. //      if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextColor)) {  
  136. //          ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderTextColor);  
  137. //          if (null != colors) {  
  138. //              setTextColor(colors);  
  139. //          }  
  140. //      }  
  141. //      if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderSubTextColor)) {  
  142. //          ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderSubTextColor);  
  143. //          if (null != colors) {  
  144. //              setSubTextColor(colors);  
  145. //          }  
  146. //      }  
  147.   
  148.         // Try and get defined drawable from Attrs  
  149.         Drawable imageDrawable = null;  
  150.         if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawable)) {  
  151.             imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawable);  
  152.         }  
  153.   
  154.         // Check Specific Drawable from Attrs, these overrite the generic  
  155.         // drawable attr above  
  156.         switch (mode) {  
  157.             case PULL_FROM_START:  
  158.             default:  
  159.                 if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableStart)) {  
  160.                     imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableStart);  
  161.                 } else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableTop)) {  
  162.                     Utils.warnDeprecation("ptrDrawableTop""ptrDrawableStart");  
  163.                     imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop);  
  164.                 }  
  165.                 break;  
  166.   
  167.             case PULL_FROM_END:  
  168.                 if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableEnd)) {  
  169.                     imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableEnd);  
  170.                 } else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableBottom)) {  
  171.                     Utils.warnDeprecation("ptrDrawableBottom""ptrDrawableEnd");  
  172.                     imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableBottom);  
  173.                 }  
  174.                 break;  
  175.         }  
  176.   
  177.         // If we don't have a user defined drawable, load the default  
  178.         if (null == imageDrawable) {  
  179.             imageDrawable = context.getResources().getDrawable(getDefaultDrawableResId());  
  180.         }  
  181.   
  182.         // Set Drawable, and save width/height  
  183.         setLoadingDrawable(imageDrawable);  
  184.   
  185.         reset();  
  186.     }  
  187.   
  188.     public final void setHeight(int height) {  
  189.         ViewGroup.LayoutParams lp = getLayoutParams();  
  190.         lp.height = height;  
  191.         requestLayout();  
  192.     }  
  193.   
  194.     public final void setWidth(int width) {  
  195.         ViewGroup.LayoutParams lp = getLayoutParams();  
  196.         lp.width = width;  
  197.         requestLayout();  
  198.     }  
  199.   
  200.     public final int getContentSize() {  
  201.         switch (mScrollDirection) {  
  202.             case HORIZONTAL:  
  203.                 return mInnerLayout.getWidth();  
  204.             case VERTICAL:  
  205.             default:  
  206.                 return mInnerLayout.getHeight();  
  207.         }  
  208.     }  
  209.   
  210.     public final void hideAllViews() {  
  211. //      if (View.VISIBLE == mHeaderText.getVisibility()) {  
  212. //          mHeaderText.setVisibility(View.INVISIBLE);  
  213. //      }  
  214. //      if (View.VISIBLE == mHeaderProgress.getVisibility()) {  
  215. //          mHeaderProgress.setVisibility(View.INVISIBLE);  
  216. //      }  
  217. //      if (View.VISIBLE == mHeaderImage.getVisibility()) {  
  218. //          mHeaderImage.setVisibility(View.INVISIBLE);  
  219. //      }  
  220. //      if (View.VISIBLE == mSubHeaderText.getVisibility()) {  
  221. //          mSubHeaderText.setVisibility(View.INVISIBLE);  
  222. //      }  
  223.     }  
  224.   
  225.     public final void onPull(float scaleOfLayout) {  
  226.         if (!mUseIntrinsicAnimation) {  
  227.             onPullImpl(scaleOfLayout);  
  228.         }  
  229.     }  
  230.   
  231.     public final void pullToRefresh() {  
  232. //      if (null != mHeaderText) {  
  233. //          mHeaderText.setText(mPullLabel);  
  234. //      }  
  235.   
  236.         // Now call the callback  
  237.         pullToRefreshImpl();  
  238.     }  
  239.   
  240.     public final void refreshing() {  
  241.         if (null != mHeaderText) {  
  242.             mHeaderText.setText(mRefreshingLabel);  
  243.         }  
  244.   
  245.         if (mUseIntrinsicAnimation) {  
  246.             ((AnimationDrawable) mHeaderImage.getDrawable()).start();  
  247.         } else {  
  248.             // Now call the callback  
  249.             refreshingImpl();  
  250.         }  
  251.   
  252. //      if (null != mSubHeaderText) {  
  253. //          mSubHeaderText.setVisibility(View.GONE);  
  254. //      }  
  255.     }  
  256.   
  257.     public final void releaseToRefresh() {  
  258. //      if (null != mHeaderText) {  
  259. //          mHeaderText.setText(mReleaseLabel);  
  260. //      }  
  261.   
  262.         // Now call the callback  
  263.         releaseToRefreshImpl();  
  264.     }  
  265.   
  266.     public final void reset() {  
  267. //      if (null != mHeaderText) {  
  268. //          mHeaderText.setText(mPullLabel);  
  269. //      }  
  270.         mHeaderImage.setVisibility(View.VISIBLE);  
  271.   
  272.         if (mUseIntrinsicAnimation) {  
  273.             ((AnimationDrawable) mHeaderImage.getDrawable()).stop();  
  274.         } else {  
  275.             // Now call the callback  
  276.             resetImpl();  
  277.         }  
  278.   
  279. //      if (null != mSubHeaderText) {  
  280. //          if (TextUtils.isEmpty(mSubHeaderText.getText())) {  
  281. //              mSubHeaderText.setVisibility(View.GONE);  
  282. //          } else {  
  283. //              mSubHeaderText.setVisibility(View.VISIBLE);  
  284. //          }  
  285. //      }  
  286.     }  
  287.   
  288.     @Override  
  289.     public void setLastUpdatedLabel(CharSequence label) {  
  290. //      setSubHeaderText(label);  
  291.     }  
  292.   
  293.     @Override  
  294.     public final void setLoadingDrawable(Drawable imageDrawable) {  
  295.         // Set Drawable  
  296.         mHeaderImage.setImageDrawable(imageDrawable);  
  297.         mUseIntrinsicAnimation = (imageDrawable instanceof AnimationDrawable);  
  298.   
  299.         // Now call the callback  
  300.         onLoadingDrawableSet(imageDrawable);  
  301.     }  
  302.   
  303.     @Override  
  304.     public void setPullLabel(CharSequence pullLabel) {  
  305.         mPullLabel = pullLabel;  
  306.     }  
  307.   
  308.     @Override  
  309.     public void setRefreshingLabel(CharSequence refreshingLabel) {  
  310.         mRefreshingLabel = refreshingLabel;  
  311.     }  
  312.   
  313.     @Override  
  314.     public void setReleaseLabel(CharSequence releaseLabel) {  
  315.         mReleaseLabel = releaseLabel;  
  316.     }  
  317.   
  318.     @Override  
  319.     public void setTextTypeface(Typeface tf) {  
  320.         mHeaderText.setTypeface(tf);  
  321.     }  
  322.   
  323.     public final void showInvisibleViews() {  
  324. //      if (View.INVISIBLE == mHeaderText.getVisibility()) {  
  325. //          mHeaderText.setVisibility(View.VISIBLE);  
  326. //      }  
  327. //      if (View.INVISIBLE == mHeaderProgress.getVisibility()) {  
  328. //          mHeaderProgress.setVisibility(View.VISIBLE);  
  329. //      }  
  330.         if (View.INVISIBLE == mHeaderImage.getVisibility()) {  
  331.             mHeaderImage.setVisibility(View.VISIBLE);  
  332.         }  
  333. //      if (View.INVISIBLE == mSubHeaderText.getVisibility()) {  
  334. //          mSubHeaderText.setVisibility(View.VISIBLE);  
  335. //      }  
  336.     }  
  337.   
  338.     /** 
  339.      * Callbacks for derivative Layouts 
  340.      */  
  341.   
  342.     protected abstract int getDefaultDrawableResId();  
  343.   
  344.     protected abstract void onLoadingDrawableSet(Drawable imageDrawable);  
  345.   
  346.     protected abstract void onPullImpl(float scaleOfLayout);  
  347.   
  348.     protected abstract void pullToRefreshImpl();  
  349.   
  350.     protected abstract void refreshingImpl();  
  351.   
  352.     protected abstract void releaseToRefreshImpl();  
  353.   
  354.     protected abstract void resetImpl();  
  355.   
  356.     private void setSubHeaderText(CharSequence label) {  
  357.         if (null != mSubHeaderText) {  
  358.             if (TextUtils.isEmpty(label)) {  
  359.                 mSubHeaderText.setVisibility(View.GONE);  
  360.             } else {  
  361.                 mSubHeaderText.setText(label);  
  362.   
  363.                 // Only set it to Visible if we're GONE, otherwise VISIBLE will  
  364.                 // be set soon  
  365.                 if (View.GONE == mSubHeaderText.getVisibility()) {  
  366.                     mSubHeaderText.setVisibility(View.VISIBLE);  
  367.                 }  
  368.             }  
  369.         }  
  370.     }  
  371.   
  372.     private void setSubTextAppearance(int value) {  
  373.         if (null != mSubHeaderText) {  
  374.             mSubHeaderText.setTextAppearance(getContext(), value);  
  375.         }  
  376.     }  
  377.   
  378.     private void setSubTextColor(ColorStateList color) {  
  379.         if (null != mSubHeaderText) {  
  380.             mSubHeaderText.setTextColor(color);  
  381.         }  
  382.     }  
  383.   
  384.     private void setTextAppearance(int value) {  
  385.         if (null != mHeaderText) {  
  386.             mHeaderText.setTextAppearance(getContext(), value);  
  387.         }  
  388.         if (null != mSubHeaderText) {  
  389.             mSubHeaderText.setTextAppearance(getContext(), value);  
  390.         }  
  391.     }  
  392.   
  393.     private void setTextColor(ColorStateList color) {  
  394.         if (null != mHeaderText) {  
  395.             mHeaderText.setTextColor(color);  
  396.         }  
  397.         if (null != mSubHeaderText) {  
  398.             mSubHeaderText.setTextColor(color);  
  399.         }  
  400.     }  
  401.   
  402. }  

还需进行以下:

更改LoadingLayout源码第78行,默认加载自定义布局;
②自定义LoadingLayout的子类,覆盖父类中的抽象方法;
③PullToRefreshBase源码第1328行createLoadingLayout方法中,默认返回自定义的LoadingLayout子类;

有一个问题,不知道为什么上下动画都改了,我只想改上边啊!!(自用)

   

        

现在第三方下拉刷新的库非常多,但是比较常用的就是PullToRefresh了,因为支持的控件比较多 但是缺点就是代码量很大 原生可定制性比较差,所以花了一些时间研究了下这个库。 话不多说,说干就干。我们先集成PullToRefresh到自己的项目。集成后项目的结构 集成完库,开始写一个简单的ListView看一下默认的效果。 1、PullToRefreshListView快速创建,看效果 MainActivity布局文件 控件初始化和加载适配器 模拟联网,两秒后设置加载完成 Adapter就是基础listView写法就不贴代码了和item自己随便写个简单的布局就好,接下来就可以看效果了。 看到这个上拉和下拉的效果,估计好多小伙伴的需求并不是要这个效果,都会要加一些自己的文字或者动画。下面我们就开始简单的定制这个上拉和下拉的布局 2、文字定制 修改文字比较简单,控件已经提供了相应的方法,直接上代码 紧紧文字的修改是远远不够的,我还要修改动画怎么办呢?下面就是引入动画 3、动画定制 接下来的定制都是需要去库里面修改代码了,可要打起精神,防止出错。 在PullTorefreshBase这个类扎到 方法;修改以下 //此处实现了我们需要 修改的动画方法: //修改代码实现 自己的下载刷新动画 LoadingLayout createLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) { switch (this) { case ROTATE: default: //帧动画 frameAnimationLayout为 自定义动画类 //通过mode判断是header还是footer if (Mode.PULL_FROM_START == mode) { return new FrameAnimationLayout(context, mode, scrollDirection, attrs); } else if (Mode.PULL_FROM_END == mode) { return new RotateLoadingLayout(context, mode, scrollDirection, attrs); } // return new RotateLoadingLayout(context, mode, scrollDirection, attrs); case FLIP: return new FlipLoadingLayout(context, mode, scrollDirection, attrs); } } 重点就在通过mode参数判断是下拉还是上拉,我可以分别修改动画。但是我还想在控件加入一些其他文字,这就需要修改Header布局文件,进入资源文件找到,问项目用的是ListView,所以要修改vertical这个布局,具体修改就看你公司需求自己定制了。 这里要说的是重点!因为这个布局文件header和footer共用的,如果有控件要在代码操作它的显示与隐藏,要在LoadingLayout类的构造器初始化对象。 在下面几行代码,还是通过mode这个参数判断是上拉还是下拉,来区分你的操作,来显示不同的头和脚。 接下来修复添加自己的控件后会有显示方面的bug, 需要在showInvisibleViews和hideAllViews两个方法分别把需要操作的控件分别显示和隐藏,要不下拉或者上拉距离过 大会导致控件偶尔不隐藏的bug。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值