├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── Android_PullToRefreshLibrary_Collection.iml ├── Phoenix ├── .gitignore ├── Phoenix.iml ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── yalantis │ │ └── phoenix │ │ ├── PullToRefreshView.java │ │ ├── refresh_view │ │ ├── BaseRefreshView.java │ │ └── SunRefreshView.java │ │ └── util │ │ ├── Logger.java │ │ └── Utils.java │ └── res │ ├── drawable-hdpi │ ├── buildings.png │ ├── sky.png │ └── sun.png │ ├── drawable-mdpi │ ├── buildings.png │ ├── sky.png │ └── sun.png │ ├── drawable-xhdpi │ ├── buildings.png │ ├── sky.png │ └── sun.png │ ├── drawable-xxhdpi │ ├── buildings.png │ ├── sky.png │ └── sun.png │ ├── drawable-xxxhdpi │ ├── buildings.png │ ├── sky.png │ └── sun.png │ └── values │ └── attrs.xml ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tellh │ │ └── android_pulltorefreshlibrary_collection │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── tellh │ │ │ └── android_pulltorefreshlibrary_collection │ │ │ ├── BaseActivity.java │ │ │ ├── CircleRefreshLayoutActivity.java │ │ │ ├── JellyRefreshActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── PullToRefreshLayoutActivity.java │ │ │ ├── PullToRefreshLayoutTellH │ │ │ └── PullToRefreshLayout.java │ │ │ ├── PullToRefreshViewPhoenixActivity.java │ │ │ ├── PullToRefreshViewTaurusActivity.java │ │ │ ├── SwipeToRefreshActivity.java │ │ │ ├── WaterDropListView │ │ │ ├── Circle.java │ │ │ ├── Utils.java │ │ │ ├── WaterDropListView.java │ │ │ ├── WaterDropListViewFooter.java │ │ │ ├── WaterDropListViewHeader.java │ │ │ └── WaterDropView.java │ │ │ ├── WaterDropListViewActivity.java │ │ │ ├── XListView │ │ │ ├── LoadView.java │ │ │ ├── XListView.java │ │ │ ├── XListViewFooter.java │ │ │ └── XListViewHeader.java │ │ │ ├── XListViewActivity.java │ │ │ └── util │ │ │ └── Logger.java │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_check_circle_black.png │ │ └── water_drop_refresh_arrow.png │ │ ├── drawable-mdpi │ │ └── ic_check_circle_black.png │ │ ├── drawable-xhdpi │ │ └── ic_check_circle_black.png │ │ ├── drawable-xxhdpi │ │ ├── ic_check_circle_black.png │ │ ├── xlistview_arrow.png │ │ └── xlistview_loading.png │ │ ├── drawable-xxxhdpi │ │ └── ic_check_circle_black.png │ │ ├── drawable │ │ ├── card_selector.xml │ │ └── down_arrow.png │ │ ├── layout │ │ ├── activity_circle_refresh.xml │ │ ├── activity_jelly_refresh.xml │ │ ├── activity_main.xml │ │ ├── activity_pull_to_refresh_phoenix.xml │ │ ├── activity_pull_to_refresh_taurus_fly_plane.xml │ │ ├── activity_pull_to_refresh_tellh.xml │ │ ├── activity_swipe_to_refresh_google.xml │ │ ├── activity_water_drop_listview.xml │ │ ├── activity_xlistview.xml │ │ ├── layout_refresh_view.xml │ │ ├── list_item.xml │ │ ├── waterdroplistview_footer.xml │ │ ├── waterdroplistview_header.xml │ │ ├── xlistview_footer.xml │ │ └── xlistview_header.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── tellh │ └── android_pulltorefreshlibrary_collection │ └── ExampleUnitTest.java ├── build.gradle ├── circlerefreshlayout ├── .gitignore ├── build.gradle ├── circlerefreshlayout.iml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tellh │ │ └── circlerefreshlayout │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── tuesda │ │ │ └── walker │ │ │ └── circlerefresh │ │ │ ├── AnimationView.java │ │ │ └── CircleRefreshLayout.java │ └── res │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── tellh │ └── circlerefreshlayout │ └── ExampleUnitTest.java ├── gif └── Refresh.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jellyrefresh ├── .gitignore ├── build.gradle ├── jellyrefresh.iml ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tellh │ │ └── jellyrefresh │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── uk │ │ │ └── co │ │ │ └── imallan │ │ │ └── jellyrefresh │ │ │ ├── JellyRefreshLayout.java │ │ │ ├── JellyView.java │ │ │ ├── JellyViewFrameLayout.java │ │ │ ├── MathUtils.java │ │ │ └── PullToRefreshLayout.java │ └── res │ │ ├── layout │ │ ├── new_view_pull_header.xml │ │ └── view_pull_header.xml │ │ └── values │ │ ├── attrs.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── tellh │ └── jellyrefresh │ └── ExampleUnitTest.java ├── settings.gradle ├── swipetorefreshlayoutgoogle ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── src │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── tellh │ │ │ └── swipetorefreshlayoutgoogle │ │ │ └── ApplicationTest.java │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── tellh │ │ │ │ └── swipetorefreshlayoutgoogle │ │ │ │ ├── CircleImageView.java │ │ │ │ ├── MaterialProgressDrawable.java │ │ │ │ ├── SwipeRefreshTestLayout.java │ │ │ │ └── util │ │ │ │ └── Logger.java │ │ └── res │ │ │ └── values │ │ │ └── strings.xml │ └── test │ │ └── java │ │ └── com │ │ └── tellh │ │ └── swipetorefreshlayoutgoogle │ │ └── ExampleUnitTest.java └── swipetorefreshlayoutgoogle.iml └── taurus_flyplane ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── src ├── androidTest │ └── java │ │ └── com │ │ └── tellh │ │ └── taurus_flyplane │ │ └── ApplicationTest.java ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── yalantis │ │ │ └── taurus │ │ │ ├── PullToRefreshView.java │ │ │ └── RefreshView.java │ └── res │ │ ├── drawable-hdpi │ │ ├── airplane.png │ │ ├── clouds_center.png │ │ ├── clouds_left.png │ │ └── clouds_right.png │ │ ├── drawable-mdpi │ │ ├── airplane.png │ │ ├── clouds_center.png │ │ ├── clouds_left.png │ │ └── clouds_right.png │ │ ├── drawable-xhdpi │ │ ├── airplane.png │ │ ├── clouds_center.png │ │ ├── clouds_left.png │ │ └── clouds_right.png │ │ ├── drawable-xxhdpi │ │ ├── airplane.png │ │ ├── clouds_center.png │ │ ├── clouds_left.png │ │ └── clouds_right.png │ │ ├── drawable-xxxhdpi │ │ ├── airplane.png │ │ ├── clouds_center.png │ │ ├── clouds_left.png │ │ └── clouds_right.png │ │ └── values │ │ ├── colors.xml │ │ └── strings.xml └── test │ └── java │ └── com │ └── tellh │ └── taurus_flyplane │ └── ExampleUnitTest.java └── taurus_flyplane.iml /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Android_PullToRefreshLibrary_Collection -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | Android API 23 Platform 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Android_PullToRefreshLibrary_Collection.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Phoenix/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Phoenix/Phoenix.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Phoenix/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 14 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | testCompile 'junit:junit:4.12' 24 | compile 'com.android.support:appcompat-v7:23.1.1' 25 | } 26 | -------------------------------------------------------------------------------- /Phoenix/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\AndroidStudio\Android\AndroidStudio/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Phoenix/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Phoenix/src/main/java/com/yalantis/phoenix/refresh_view/BaseRefreshView.java: -------------------------------------------------------------------------------- 1 | package com.yalantis.phoenix.refresh_view; 2 | 3 | import android.content.Context; 4 | import android.graphics.ColorFilter; 5 | import android.graphics.PixelFormat; 6 | import android.graphics.drawable.Animatable; 7 | import android.graphics.drawable.Drawable; 8 | import android.support.annotation.NonNull; 9 | 10 | import com.yalantis.phoenix.PullToRefreshView; 11 | 12 | public abstract class BaseRefreshView extends Drawable implements Drawable.Callback, Animatable { 13 | 14 | private final PullToRefreshView mRefreshLayout; 15 | private boolean mEndOfRefreshing; 16 | 17 | public BaseRefreshView(Context context, PullToRefreshView layout) { 18 | mRefreshLayout = layout; 19 | } 20 | 21 | public Context getContext() { 22 | return mRefreshLayout != null ? mRefreshLayout.getContext() : null; 23 | } 24 | 25 | public PullToRefreshView getRefreshLayout() { 26 | return mRefreshLayout; 27 | } 28 | 29 | public abstract void setPercent(float percent, boolean invalidate); 30 | 31 | public abstract void offsetTopAndBottom(int offset); 32 | 33 | @Override 34 | public void invalidateDrawable(@NonNull Drawable who) { 35 | final Callback callback = getCallback(); 36 | if (callback != null) { 37 | callback.invalidateDrawable(this); 38 | } 39 | } 40 | 41 | @Override 42 | public void scheduleDrawable(Drawable who, Runnable what, long when) { 43 | final Callback callback = getCallback(); 44 | if (callback != null) { 45 | callback.scheduleDrawable(this, what, when); 46 | } 47 | } 48 | 49 | @Override 50 | public void unscheduleDrawable(Drawable who, Runnable what) { 51 | final Callback callback = getCallback(); 52 | if (callback != null) { 53 | callback.unscheduleDrawable(this, what); 54 | } 55 | } 56 | 57 | @Override 58 | public int getOpacity() { 59 | return PixelFormat.TRANSLUCENT; 60 | } 61 | 62 | @Override 63 | public void setAlpha(int alpha) { 64 | 65 | } 66 | 67 | @Override 68 | public void setColorFilter(ColorFilter cf) { 69 | 70 | } 71 | 72 | /** 73 | * Our animation depend on type of current work of refreshing. 74 | * We should to do different things when it's end of refreshing 75 | * 76 | * @param endOfRefreshing - we will check current state of refresh with this 77 | */ 78 | public void setEndOfRefreshing(boolean endOfRefreshing) { 79 | mEndOfRefreshing = endOfRefreshing; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Phoenix/src/main/java/com/yalantis/phoenix/util/Logger.java: -------------------------------------------------------------------------------- 1 | package com.yalantis.phoenix.util; 2 | 3 | import android.text.TextUtils; 4 | 5 | public final class Logger { 6 | 7 | private static final String TAG = "Phoenix"; 8 | 9 | /** 10 | * Set true or false if you want read logs or not 11 | */ 12 | private static boolean logEnabled_d = true; 13 | private static boolean logEnabled_i = false; 14 | private static boolean logEnabled_e = false; 15 | 16 | private Logger () {} 17 | 18 | public static void d() { 19 | if (logEnabled_d) { 20 | android.util.Log.v(TAG, getLocation()); 21 | } 22 | } 23 | 24 | public static void d(String msg) { 25 | if (logEnabled_d) { 26 | android.util.Log.v(TAG, getLocation() + msg); 27 | } 28 | } 29 | 30 | public static void i(String msg) { 31 | if (logEnabled_i) { 32 | android.util.Log.i(TAG, getLocation() + msg); 33 | } 34 | } 35 | 36 | public static void i() { 37 | if (logEnabled_i) { 38 | android.util.Log.i(TAG, getLocation()); 39 | } 40 | } 41 | 42 | public static void e(String msg) { 43 | if (logEnabled_e) { 44 | android.util.Log.e(TAG, getLocation() + msg); 45 | } 46 | } 47 | 48 | public static void e(String msg, Throwable e) { 49 | if (logEnabled_e) { 50 | android.util.Log.e(TAG, getLocation() + msg, e); 51 | } 52 | } 53 | 54 | public static void e(Throwable e) { 55 | if (logEnabled_e) { 56 | android.util.Log.e(TAG, getLocation(), e); 57 | } 58 | } 59 | 60 | public static void e() { 61 | if (logEnabled_e) { 62 | android.util.Log.e(TAG, getLocation()); 63 | } 64 | } 65 | 66 | private static String getLocation() { 67 | final String className = Logger.class.getName(); 68 | final StackTraceElement[] traces = Thread.currentThread() 69 | .getStackTrace(); 70 | boolean found = false; 71 | 72 | for (StackTraceElement trace : traces) { 73 | try { 74 | if (found) { 75 | if (!trace.getClassName().startsWith(className)) { 76 | Class clazz = Class.forName(trace.getClassName()); 77 | return "[" + getClassName(clazz) + ":" 78 | + trace.getMethodName() + ":" 79 | + trace.getLineNumber() + "]: "; 80 | } 81 | } else if (trace.getClassName().startsWith(className)) { 82 | found = true; 83 | } 84 | } catch (ClassNotFoundException ignored) { 85 | } 86 | } 87 | 88 | return "[]: "; 89 | } 90 | 91 | private static String getClassName(Class clazz) { 92 | if (clazz != null) { 93 | if (!TextUtils.isEmpty(clazz.getSimpleName())) { 94 | return clazz.getSimpleName(); 95 | } 96 | 97 | return getClassName(clazz.getEnclosingClass()); 98 | } 99 | 100 | return ""; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /Phoenix/src/main/java/com/yalantis/phoenix/util/Utils.java: -------------------------------------------------------------------------------- 1 | package com.yalantis.phoenix.util; 2 | 3 | import android.content.Context; 4 | 5 | public class Utils { 6 | 7 | private Utils() {} 8 | 9 | public static int convertDpToPixel(Context context, int dp) { 10 | float density = context.getResources().getDisplayMetrics().density; 11 | return Math.round((float) dp * density); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-hdpi/buildings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-hdpi/buildings.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-hdpi/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-hdpi/sky.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-hdpi/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-hdpi/sun.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-mdpi/buildings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-mdpi/buildings.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-mdpi/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-mdpi/sky.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-mdpi/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-mdpi/sun.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xhdpi/buildings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xhdpi/buildings.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xhdpi/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xhdpi/sky.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xhdpi/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xhdpi/sun.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xxhdpi/buildings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xxhdpi/buildings.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xxhdpi/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xxhdpi/sky.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xxhdpi/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xxhdpi/sun.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xxxhdpi/buildings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xxxhdpi/buildings.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xxxhdpi/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xxxhdpi/sky.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/drawable-xxxhdpi/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/Phoenix/src/main/res/drawable-xxxhdpi/sun.png -------------------------------------------------------------------------------- /Phoenix/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android_PullToRefreshLibrary_Collection 2 | Android下拉刷新开源库集锦,提供源码用于学习和研究 3 | # 前几个库的源码已添加详细的注释,方便阅读。 4 | ## 包含有Google官方的SwipeRefreshLayout的源码解析,同时修改了其中的两个bug 5 | * 设置下拉将圆圈缩放时,出现缩放异常 6 | * 在Activity的onCreate()方法中调用SwipeRefreshLayout.setRefresh(true);没有效果的问题
7 | 8 | 9 | 详情请参考博文:[解读Google官方SwipeRefreshLayout控件源码,带你揭秘Android下拉刷新的实现原理](http://blog.csdn.net/tellh/article/details/50782653) 10 | 11 | ## [XListview](https://github.com/Maxwin-z/XListView-Android)的源码注释已完成 12 | ## [Phoenix](https://github.com/Yalantis/Phoenix)([Taurus](https://github.com/Yalantis/Taurus)也是一样的)的PullToRefreshView源码注释已完成 13 | ## 我的[PullToRefreshLayout](https://github.com/TellH/Android-Simple-Common-PullToRefreshLayout)的源码注释已完成 14 | 15 | # 效果图: 16 | ![](https://github.com/TellH/Android_PullToRefreshLibrary_Collection/blob/master/gif/Refresh.gif) 17 | #contribute 18 | 该demo还会逐渐完善,如果你有好的下拉刷新开源库推荐,欢迎fork and pull request! 19 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.tellh.android_pulltorefreshlibrary_collection" 9 | minSdkVersion 14 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.1.1' 26 | compile 'com.android.support:design:23.1.1' 27 | compile 'com.android.support:cardview-v7:23.1.1' 28 | compile project(':swipetorefreshlayoutgoogle') 29 | compile project(':Phoenix') 30 | compile project(':taurus_flyplane') 31 | compile project(':jellyrefresh') 32 | compile project(':circlerefreshlayout') 33 | } 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\AndroidStudio\Android\AndroidStudio/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tellh/android_pulltorefreshlibrary_collection/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.ListView; 12 | import android.widget.TextView; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by tlh on 2016/3/1. 19 | */ 20 | public abstract class BaseActivity extends AppCompatActivity { 21 | public List mList; 22 | public ListView listView; 23 | @Override 24 | public void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(getLayoutId()); 27 | mList=new ArrayList<>(); 28 | for (int i = 0; i < 20; i++) { 29 | mList.add(String.valueOf(i)); 30 | } 31 | listView= (ListView) findViewById(R.id.list_view); 32 | listView.setAdapter(new SampleAdapter(this, R.layout.list_item, mList)); 33 | 34 | initView(); 35 | } 36 | 37 | public void initView() { 38 | 39 | } 40 | 41 | abstract public int getLayoutId(); 42 | 43 | class SampleAdapter extends ArrayAdapter { 44 | 45 | private final LayoutInflater mInflater; 46 | private final List mData; 47 | 48 | public SampleAdapter(Context context, int layoutResourceId, List data) { 49 | super(context, layoutResourceId, data); 50 | mData = data; 51 | mInflater = LayoutInflater.from(context); 52 | } 53 | 54 | @Override 55 | public View getView(final int position, View convertView, @NonNull ViewGroup parent) { 56 | final ViewHolder viewHolder; 57 | if (convertView == null) { 58 | viewHolder = new ViewHolder(); 59 | convertView = mInflater.inflate(R.layout.list_item, parent, false); 60 | viewHolder.tvNum= (TextView) convertView.findViewById(R.id.tv_num); 61 | convertView.setTag(viewHolder); 62 | } else { 63 | viewHolder = (ViewHolder) convertView.getTag(); 64 | } 65 | 66 | viewHolder.tvNum.setText(mData.get(position)); 67 | return convertView; 68 | } 69 | 70 | class ViewHolder { 71 | TextView tvNum; 72 | } 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/CircleRefreshLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import com.tuesda.walker.circlerefresh.CircleRefreshLayout; 5 | 6 | public class CircleRefreshLayoutActivity extends BaseActivity { 7 | 8 | 9 | private CircleRefreshLayout mRefreshLayout; 10 | 11 | @Override 12 | public int getLayoutId() { 13 | return R.layout.activity_circle_refresh; 14 | } 15 | 16 | @Override 17 | public void initView() { 18 | mRefreshLayout = (CircleRefreshLayout) findViewById(R.id.refresh_widget); 19 | mRefreshLayout.setOnRefreshListener(new CircleRefreshLayout.OnCircleRefreshListener() { 20 | @Override 21 | public void completeRefresh() { 22 | 23 | } 24 | 25 | @Override 26 | public void refreshing() { 27 | mRefreshLayout.postDelayed(new Runnable() { 28 | @Override 29 | public void run() { 30 | mRefreshLayout.finishRefreshing(); 31 | } 32 | }, 3000); 33 | } 34 | 35 | }); 36 | } 37 | 38 | @Override 39 | public void onBackPressed() { 40 | if (mRefreshLayout.isRefreshing()) { 41 | mRefreshLayout.finishRefreshing(); 42 | return; 43 | } 44 | super.onBackPressed(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/JellyRefreshActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import uk.co.imallan.jellyrefresh.JellyRefreshLayout; 5 | 6 | public class JellyRefreshActivity extends BaseActivity { 7 | 8 | 9 | private JellyRefreshLayout mRefreshLayout; 10 | 11 | @Override 12 | public int getLayoutId() { 13 | return R.layout.activity_jelly_refresh; 14 | } 15 | 16 | @Override 17 | public void initView() { 18 | mRefreshLayout = (JellyRefreshLayout) findViewById(R.id.refresh_widget); 19 | mRefreshLayout.setRefreshListener(new JellyRefreshLayout.JellyRefreshListener() { 20 | @Override 21 | public void onRefresh(JellyRefreshLayout jellyRefreshLayout) { 22 | mRefreshLayout.postDelayed(new Runnable() { 23 | @Override 24 | public void run() { 25 | mRefreshLayout.finishRefreshing(); 26 | } 27 | }, 3000); 28 | } 29 | }); 30 | } 31 | 32 | @Override 33 | public void onBackPressed() { 34 | if (mRefreshLayout.isRefreshing()) { 35 | mRefreshLayout.finishRefreshing(); 36 | return; 37 | } 38 | super.onBackPressed(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | 8 | 9 | public class MainActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_main); 15 | } 16 | 17 | public void onClick(View v) { 18 | switch (v.getId()) { 19 | case R.id.btn_swipe_to_refresh_layout_google: 20 | startActivity(new Intent(MainActivity.this, SwipeToRefreshActivity.class)); 21 | break; 22 | case R.id.btn_pull_to_refresh_view_phoenix: 23 | startActivity(new Intent(MainActivity.this, PullToRefreshViewPhoenixActivity.class)); 24 | break; 25 | case R.id.btn_pull_to_refresh_view_tellh: 26 | startActivity(new Intent(MainActivity.this, PullToRefreshLayoutActivity.class)); 27 | break; 28 | case R.id.btn_xlistview: 29 | startActivity(new Intent(MainActivity.this, XListViewActivity.class)); 30 | break; 31 | case R.id.btn_pull_to_refresh_view_taurus_fly_plane: 32 | startActivity(new Intent(MainActivity.this, PullToRefreshViewTaurusActivity.class)); 33 | break; 34 | case R.id.btn_jelly_refresh: 35 | startActivity(new Intent(MainActivity.this, JellyRefreshActivity.class)); 36 | break; 37 | case R.id.btn_circle_refresh: 38 | startActivity(new Intent(MainActivity.this, CircleRefreshLayoutActivity.class)); 39 | break; 40 | case R.id.btn_water_drop_listview: 41 | startActivity(new Intent(MainActivity.this, WaterDropListViewActivity.class)); 42 | break; 43 | // case R.id.btn_ultra_refresh_layout: 44 | // startActivity(new Intent(MainActivity.this, UltraPullToRefreshActivity.class)); 45 | // break; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/PullToRefreshLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import android.annotation.TargetApi; 5 | import android.os.Build; 6 | import android.view.View; 7 | import android.widget.ImageView; 8 | import android.widget.ProgressBar; 9 | import android.widget.TextView; 10 | 11 | import com.tellh.android_pulltorefreshlibrary_collection.PullToRefreshLayoutTellH.PullToRefreshLayout; 12 | 13 | public class PullToRefreshLayoutActivity extends BaseActivity { 14 | 15 | 16 | private PullToRefreshLayout mRefreshLayout; 17 | private ProgressBar progressBar; 18 | private TextView textView; 19 | private ImageView imageView; 20 | private ImageView imgDone; 21 | 22 | @Override 23 | public int getLayoutId() { 24 | return R.layout.activity_pull_to_refresh_tellh; 25 | } 26 | 27 | @Override 28 | public void initView() { 29 | mRefreshLayout = (PullToRefreshLayout) findViewById(R.id.refresh_widget); 30 | createRefreshView(); 31 | mRefreshLayout.setOnRefreshListener(new PullToRefreshLayout.OnRefreshListenerAdapter() { 32 | @Override 33 | public void onRefresh() { 34 | textView.setText("正在刷新"); 35 | imgDone.setVisibility(View.GONE); 36 | imageView.setVisibility(View.INVISIBLE); 37 | progressBar.setVisibility(View.VISIBLE); 38 | mRefreshLayout.postDelayed(new Runnable() { 39 | @Override 40 | public void run() { 41 | mRefreshLayout.setRefreshing(false); 42 | } 43 | }, 2000); 44 | } 45 | 46 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 47 | @Override 48 | public void onDragDistanceChange(float distance, float percent, float offset) { 49 | if (percent >= 1.0f) { 50 | textView.setText("松开刷新"); 51 | imgDone.setVisibility(View.GONE); 52 | imageView.setVisibility(View.VISIBLE); 53 | imageView.setRotation(180); 54 | } else { 55 | textView.setText("下拉刷新"); 56 | imgDone.setVisibility(View.GONE); 57 | imageView.setVisibility(View.VISIBLE); 58 | imageView.setRotation(0); 59 | } 60 | } 61 | 62 | @Override 63 | public void onFinish() { 64 | textView.setText("刷新成功"); 65 | imageView.setVisibility(View.GONE); 66 | progressBar.setVisibility(View.GONE); 67 | imgDone.setVisibility(View.VISIBLE); 68 | } 69 | }); 70 | mRefreshLayout.setFinishRefreshToPauseDuration(800); 71 | mRefreshLayout.setRefreshing(true); 72 | } 73 | 74 | private View createRefreshView() { 75 | View headerView=mRefreshLayout.setRefreshView(R.layout.layout_refresh_view); 76 | progressBar = (ProgressBar) headerView.findViewById(R.id.pb_view); 77 | textView = (TextView) headerView.findViewById(R.id.text_view); 78 | textView.setText("下拉刷新"); 79 | imageView = (ImageView) headerView.findViewById(R.id.image_view); 80 | imageView.setVisibility(View.VISIBLE); 81 | imageView.setImageResource(R.drawable.down_arrow); 82 | imgDone=(ImageView)headerView.findViewById(R.id.img_done); 83 | imgDone.setImageResource(R.drawable.ic_check_circle_black); 84 | imgDone.setVisibility(View.GONE); 85 | progressBar.setVisibility(View.GONE); 86 | return headerView; 87 | } 88 | 89 | @Override 90 | public void onBackPressed() { 91 | if (mRefreshLayout.isRefreshing()) { 92 | mRefreshLayout.setRefreshing(false); 93 | return; 94 | } 95 | super.onBackPressed(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/PullToRefreshViewPhoenixActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import com.yalantis.phoenix.PullToRefreshView; 5 | 6 | public class PullToRefreshViewPhoenixActivity extends BaseActivity { 7 | 8 | 9 | private PullToRefreshView mRefreshLayout; 10 | 11 | @Override 12 | public int getLayoutId() { 13 | return R.layout.activity_pull_to_refresh_phoenix; 14 | } 15 | 16 | @Override 17 | public void initView() { 18 | mRefreshLayout = (PullToRefreshView) findViewById(R.id.refresh_widget); 19 | mRefreshLayout.setRefreshing(true); 20 | mRefreshLayout.postDelayed(new Runnable() { 21 | @Override 22 | public void run() { 23 | mRefreshLayout.setRefreshing(false); 24 | } 25 | }, 3000); 26 | } 27 | 28 | @Override 29 | public void onBackPressed() { 30 | if (mRefreshLayout.isRefreshing()) { 31 | mRefreshLayout.setRefreshing(false); 32 | return; 33 | } 34 | super.onBackPressed(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/PullToRefreshViewTaurusActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | 5 | public class PullToRefreshViewTaurusActivity extends BaseActivity { 6 | 7 | 8 | private com.yalantis.taurus.PullToRefreshView mRefreshLayout; 9 | 10 | @Override 11 | public int getLayoutId() { 12 | return R.layout.activity_pull_to_refresh_taurus_fly_plane; 13 | } 14 | 15 | @Override 16 | public void initView() { 17 | mRefreshLayout = (com.yalantis.taurus.PullToRefreshView) findViewById(R.id.refresh_widget); 18 | mRefreshLayout.setRefreshing(true); 19 | mRefreshLayout.postDelayed(new Runnable() { 20 | @Override 21 | public void run() { 22 | mRefreshLayout.setRefreshing(false); 23 | } 24 | }, 3000); 25 | } 26 | 27 | @Override 28 | public void onBackPressed() { 29 | if (mRefreshLayout.isRefreshing()) { 30 | mRefreshLayout.setRefreshing(false); 31 | return; 32 | } 33 | super.onBackPressed(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/SwipeToRefreshActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import com.tellh.android_pulltorefreshlibrary_collection.util.Logger; 5 | import com.tellh.swipetorefreshlayoutgoogle.SwipeRefreshTestLayout; 6 | 7 | public class SwipeToRefreshActivity extends BaseActivity { 8 | 9 | 10 | private SwipeRefreshTestLayout mRefreshLayout; 11 | 12 | @Override 13 | public int getLayoutId() { 14 | Logger.d(); 15 | return R.layout.activity_swipe_to_refresh_google; 16 | } 17 | 18 | @Override 19 | public void initView() { 20 | mRefreshLayout = (SwipeRefreshTestLayout) findViewById(R.id.refresh_widget); 21 | mRefreshLayout.setEnableSpinnerScale(true); 22 | mRefreshLayout.setRefreshing(true); 23 | // new Handler().postDelayed(new Runnable() { 24 | // @Override 25 | // public void run() { 26 | // mRefreshLayout.setRefreshing(true); 27 | // } 28 | // },100); 29 | 30 | // mRefreshLayout.postDelayed(new Runnable() { 31 | // @Override 32 | // public void run() { 33 | // mRefreshLayout.setRefreshing(false); 34 | // } 35 | // }, 3000); 36 | } 37 | 38 | 39 | @Override 40 | public void onWindowFocusChanged(boolean hasFocus) { 41 | super.onWindowFocusChanged(hasFocus); 42 | com.tellh.swipetorefreshlayoutgoogle.util.Logger.d("mRefreshLayout.isActivated();" + mRefreshLayout.isShown()); 43 | // mRefreshLayout.setRefreshing(true); 44 | } 45 | 46 | @Override 47 | public void onBackPressed() { 48 | if (mRefreshLayout.isRefreshing()) { 49 | mRefreshLayout.setRefreshing(false); 50 | return; 51 | } 52 | super.onBackPressed(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/WaterDropListView/Circle.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection.WaterDropListView; 2 | 3 | /** 4 | * Created by xiayong on 2015/6/25. 5 | * 实心圆 6 | */ 7 | public class Circle { 8 | private float x;//圆x坐标 9 | private float y;//圆y坐标 10 | private float radius;//圆半径 11 | private int color;//圆的颜色 12 | 13 | public float getX() { 14 | return x; 15 | } 16 | 17 | public void setX(float x) { 18 | this.x = x; 19 | } 20 | 21 | public float getY() { 22 | return y; 23 | } 24 | 25 | public void setY(float y) { 26 | this.y = y; 27 | } 28 | 29 | public float getRadius() { 30 | return radius; 31 | } 32 | 33 | public void setRadius(float radius) { 34 | this.radius = radius; 35 | } 36 | 37 | public int getColor() { 38 | return color; 39 | } 40 | 41 | public void setColor(int color) { 42 | this.color = color; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/WaterDropListView/Utils.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection.WaterDropListView; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Canvas; 5 | import android.graphics.PixelFormat; 6 | import android.graphics.drawable.Drawable; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | /** 11 | * Created by xiayong on 2015/6/27. 12 | */ 13 | public class Utils { 14 | 15 | private Utils() {} 16 | 17 | /** 18 | * Map a value within a given range to another range. 19 | * @param value the value to map 20 | * @param fromLow the low end of the range the value is within 21 | * @param fromHigh the high end of the range the value is within 22 | * @param toLow the low end of the range to map to 23 | * @param toHigh the high end of the range to map to 24 | * @return the mapped value 25 | */ 26 | public static double mapValueFromRangeToRange( 27 | double value, 28 | double fromLow, 29 | double fromHigh, 30 | double toLow, 31 | double toHigh) { 32 | double fromRangeSize = fromHigh - fromLow; 33 | double toRangeSize = toHigh - toLow; 34 | double valueScale = (value - fromLow) / fromRangeSize; 35 | return toLow + (valueScale * toRangeSize); 36 | } 37 | 38 | /** 39 | * set margins of the specific view 40 | * @param target 41 | * @param l 42 | * @param t 43 | * @param r 44 | * @param b 45 | */ 46 | public static void setMargin(View target, int l, int t, int r, int b){ 47 | if (target.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { 48 | ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) target.getLayoutParams(); 49 | p.setMargins(l, t, r, b); 50 | target.requestLayout(); 51 | } 52 | } 53 | 54 | /** 55 | * convert drawable to bitmap 56 | * @param drawable 57 | * @return 58 | */ 59 | public static Bitmap drawableToBitmap(Drawable drawable) { 60 | int width = drawable.getIntrinsicWidth(); 61 | int height = drawable.getIntrinsicHeight(); 62 | Bitmap bitmap = Bitmap.createBitmap(width, height, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); 63 | Canvas canvas = new Canvas(bitmap); 64 | drawable.setBounds(0, 0, width, height); 65 | drawable.draw(canvas); 66 | return bitmap; 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/WaterDropListView/WaterDropListViewFooter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @file XFooterView.java 3 | * @create Mar 31, 2012 9:33:43 PM 4 | * @author Maxwin 5 | * @description XListView's footer 6 | */ 7 | package com.tellh.android_pulltorefreshlibrary_collection.WaterDropListView; 8 | 9 | 10 | import android.content.Context; 11 | import android.util.AttributeSet; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.widget.LinearLayout; 15 | import android.widget.TextView; 16 | 17 | import com.tellh.android_pulltorefreshlibrary_collection.R; 18 | 19 | 20 | public class WaterDropListViewFooter extends LinearLayout { 21 | private Context mContext; 22 | 23 | private View mContentView; 24 | private View mProgressBar; 25 | private TextView mHintView; 26 | private TextView txt_progresstext; 27 | private LinearLayout layout_progress; 28 | public enum STATE{ 29 | normal, 30 | ready, 31 | loading 32 | } 33 | public WaterDropListViewFooter(Context context) { 34 | super(context); 35 | initView(context); 36 | } 37 | 38 | public WaterDropListViewFooter(Context context, AttributeSet attrs) { 39 | super(context, attrs); 40 | initView(context); 41 | } 42 | 43 | 44 | public void setState(STATE state) { 45 | mHintView.setVisibility(View.INVISIBLE); 46 | mProgressBar.setVisibility(View.INVISIBLE); 47 | mHintView.setVisibility(View.INVISIBLE); 48 | txt_progresstext.setVisibility(View.INVISIBLE); 49 | layout_progress.setVisibility(View.INVISIBLE); 50 | if (state == STATE.ready) { 51 | mHintView.setVisibility(View.VISIBLE); 52 | mHintView.setText("松开加载更多"); 53 | } else if (state == STATE.loading) { 54 | mProgressBar.setVisibility(View.VISIBLE); 55 | layout_progress.setVisibility(View.VISIBLE); 56 | txt_progresstext.setVisibility(View.VISIBLE); 57 | } else { 58 | mHintView.setVisibility(View.VISIBLE); 59 | mHintView.setText("加载更多"); 60 | } 61 | } 62 | 63 | public void setBottomMargin(int height) { 64 | if (height < 0) return ; 65 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 66 | lp.bottomMargin = height; 67 | mContentView.setLayoutParams(lp); 68 | } 69 | 70 | public int getBottomMargin() { 71 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 72 | return lp.bottomMargin; 73 | } 74 | 75 | /** 76 | * normal status 77 | */ 78 | public void normal() { 79 | mHintView.setVisibility(View.VISIBLE); 80 | mProgressBar.setVisibility(View.GONE); 81 | layout_progress.setVisibility(View.GONE); 82 | txt_progresstext.setVisibility(View.GONE); 83 | } 84 | 85 | 86 | /** 87 | * loading status 88 | */ 89 | public void loading() { 90 | mHintView.setVisibility(View.GONE); 91 | mProgressBar.setVisibility(View.VISIBLE); 92 | layout_progress.setVisibility(View.VISIBLE); 93 | txt_progresstext.setVisibility(View.VISIBLE); 94 | } 95 | 96 | /** 97 | * hide footer when disable pull load more 98 | */ 99 | public void hide() { 100 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 101 | lp.height = 0; 102 | mContentView.setLayoutParams(lp); 103 | } 104 | 105 | /** 106 | * show footer 107 | */ 108 | public void show() { 109 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 110 | lp.height = LayoutParams.WRAP_CONTENT; 111 | mContentView.setLayoutParams(lp); 112 | } 113 | 114 | private void initView(Context context) { 115 | mContext = context; 116 | LinearLayout moreView = (LinearLayout)LayoutInflater.from(mContext).inflate(R.layout.waterdroplistview_footer, null); 117 | addView(moreView); 118 | moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 119 | 120 | mContentView = moreView.findViewById(R.id.waterdroplistview_footer_content); 121 | mProgressBar = moreView.findViewById(R.id.waterdroplistview_footer_progressbar); 122 | mHintView = (TextView)moreView.findViewById(R.id.waterdroplistview_footer_hint_textview); 123 | layout_progress=(LinearLayout)moreView.findViewById(R.id.progresslayout); 124 | txt_progresstext =(TextView)moreView.findViewById(R.id.txt_progresstext); 125 | } 126 | 127 | 128 | } 129 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/WaterDropListView/WaterDropListViewHeader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @file XListViewHeader.java 3 | * @create Apr 18, 2012 5:22:27 PM 4 | * @author Maxwin 5 | * @description XListView's header 6 | */ 7 | package com.tellh.android_pulltorefreshlibrary_collection.WaterDropListView; 8 | 9 | import android.animation.Animator; 10 | import android.animation.AnimatorListenerAdapter; 11 | import android.content.Context; 12 | import android.util.AttributeSet; 13 | import android.util.Log; 14 | import android.view.Gravity; 15 | import android.view.LayoutInflater; 16 | import android.view.View; 17 | import android.view.ViewTreeObserver; 18 | import android.widget.FrameLayout; 19 | import android.widget.LinearLayout; 20 | import android.widget.ProgressBar; 21 | 22 | import com.tellh.android_pulltorefreshlibrary_collection.R; 23 | 24 | public class WaterDropListViewHeader extends FrameLayout { 25 | private LinearLayout mContainer; 26 | private ProgressBar mProgressBar; 27 | private WaterDropView mWaterDropView; 28 | private STATE mState = STATE.normal; 29 | private IStateChangedListener mStateChangedListener; 30 | 31 | private int stretchHeight; 32 | private int readyHeight; 33 | private static final int DISTANCE_BETWEEN_STRETCH_READY = 250; 34 | 35 | public enum STATE { 36 | normal,//正常 37 | stretch,//准备进行拉伸 38 | ready,//拉伸到最大位置 39 | refreshing,//刷新 40 | end//刷新结束,回滚 41 | } 42 | 43 | public WaterDropListViewHeader(Context context) { 44 | super(context); 45 | initView(context); 46 | } 47 | 48 | /** 49 | * @param context 50 | * @param attrs 51 | */ 52 | public WaterDropListViewHeader(Context context, AttributeSet attrs) { 53 | super(context, attrs); 54 | initView(context); 55 | } 56 | 57 | private void initView(Context context) { 58 | mContainer = (LinearLayout) LayoutInflater.from(context).inflate( 59 | R.layout.waterdroplistview_header, null); 60 | mProgressBar = (ProgressBar) mContainer.findViewById(R.id.waterdroplist_header_progressbar); 61 | mWaterDropView = (WaterDropView) mContainer.findViewById(R.id.waterdroplist_waterdrop); 62 | // 初始情况,设置下拉刷新view高度为0 63 | LayoutParams lp = new LayoutParams( 64 | LayoutParams.MATCH_PARENT, 0); 65 | addView(mContainer, lp); 66 | initHeight(); 67 | } 68 | 69 | private void initHeight(){ 70 | 71 | mContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 72 | @Override 73 | public void onGlobalLayout() { 74 | stretchHeight = mWaterDropView.getHeight(); 75 | readyHeight = stretchHeight + DISTANCE_BETWEEN_STRETCH_READY; 76 | getViewTreeObserver().removeGlobalOnLayoutListener(this); 77 | } 78 | }); 79 | 80 | } 81 | /** 82 | * 修改状态。注:状态的改变与前一个状态以及下拉头高度有关 83 | * 84 | * @param state 85 | */ 86 | public void updateState(STATE state) { 87 | if (state == mState) return; 88 | STATE oldState = mState; 89 | mState = state; 90 | if (mStateChangedListener != null) { 91 | mStateChangedListener.notifyStateChanged(oldState, mState); 92 | } 93 | 94 | switch (mState) { 95 | case normal: 96 | handleStateNormal(); 97 | break; 98 | case stretch: 99 | handleStateStretch(); 100 | break; 101 | case ready: 102 | handleStateReady(); 103 | break; 104 | case refreshing: 105 | handleStateRefreshing(); 106 | break; 107 | case end: 108 | handleStateEnd(); 109 | break; 110 | default: 111 | } 112 | } 113 | 114 | /** 115 | * 处理处于normal状态的值 116 | */ 117 | private void handleStateNormal() { 118 | mWaterDropView.setVisibility(View.VISIBLE); 119 | mProgressBar.setVisibility(View.GONE); 120 | mContainer.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); 121 | } 122 | 123 | /** 124 | * 处理水滴拉伸状态 125 | */ 126 | private void handleStateStretch() { 127 | mWaterDropView.setVisibility(View.VISIBLE); 128 | mProgressBar.setVisibility(View.GONE); 129 | mContainer.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL); 130 | } 131 | 132 | /** 133 | * 处理水滴ready状态,回弹效果 134 | */ 135 | private void handleStateReady() { 136 | mWaterDropView.setVisibility(View.VISIBLE); 137 | mProgressBar.setVisibility(View.GONE); 138 | Animator shrinkAnimator = mWaterDropView.createAnimator(); 139 | shrinkAnimator.addListener(new AnimatorListenerAdapter() { 140 | @Override 141 | public void onAnimationEnd(Animator animation) { 142 | //回弹结束后即进入refreshing状态 143 | updateState(STATE.refreshing); 144 | } 145 | }); 146 | shrinkAnimator.start();//开始回弹 147 | } 148 | 149 | /** 150 | * 处理正在进行刷新状态 151 | */ 152 | private void handleStateRefreshing() { 153 | mWaterDropView.setVisibility(View.GONE); 154 | mProgressBar.setVisibility(View.VISIBLE); 155 | } 156 | 157 | /** 158 | * 处理刷新完毕状态 159 | */ 160 | private void handleStateEnd() { 161 | mWaterDropView.setVisibility(View.GONE); 162 | mProgressBar.setVisibility(View.GONE); 163 | } 164 | 165 | public void setVisiableHeight(int height) { 166 | if (height < 0) 167 | height = 0; 168 | LayoutParams lp = (LayoutParams) mContainer 169 | .getLayoutParams(); 170 | lp.height = height; 171 | mContainer.setLayoutParams(lp); 172 | //通知水滴进行更新 173 | if(mState == STATE.stretch){ 174 | float pullOffset = (float) Utils.mapValueFromRangeToRange(height, stretchHeight, readyHeight, 0, 1); 175 | if(pullOffset < 0 || pullOffset >1){ 176 | throw new IllegalArgumentException("pullOffset should between 0 and 1!"+mState+" "+height); 177 | } 178 | Log.e("pullOffset", "pullOffset:" + pullOffset); 179 | mWaterDropView.updateComleteState(pullOffset); 180 | } 181 | 182 | } 183 | 184 | 185 | public int getVisiableHeight() { 186 | return mContainer.getHeight(); 187 | } 188 | 189 | public STATE getCurrentState() { 190 | return mState; 191 | } 192 | 193 | public int getStretchHeight() { 194 | return stretchHeight; 195 | } 196 | 197 | public int getReadyHeight() { 198 | return readyHeight; 199 | } 200 | 201 | public void setStateChangedListener(IStateChangedListener l) { 202 | mStateChangedListener = l; 203 | } 204 | 205 | public interface IStateChangedListener { 206 | public void notifyStateChanged(STATE oldState, STATE newState); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/WaterDropListViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import com.tellh.android_pulltorefreshlibrary_collection.WaterDropListView.WaterDropListView; 5 | 6 | public class WaterDropListViewActivity extends BaseActivity { 7 | 8 | 9 | @Override 10 | public int getLayoutId() { 11 | return R.layout.activity_water_drop_listview; 12 | } 13 | 14 | @Override 15 | public void initView() { 16 | } 17 | 18 | 19 | @Override 20 | public void onBackPressed() { 21 | if (((WaterDropListView)listView).isRefreshing()){ 22 | ((WaterDropListView)listView).stopRefresh(); 23 | return; 24 | } 25 | super.onBackPressed(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/XListView/LoadView.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection.XListView; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.Matrix; 7 | import android.os.Handler; 8 | import android.os.Message; 9 | import android.util.AttributeSet; 10 | import android.widget.ImageView; 11 | 12 | import com.tellh.android_pulltorefreshlibrary_collection.R; 13 | 14 | import java.util.Timer; 15 | import java.util.TimerTask; 16 | 17 | /** 18 | * Created by limxing on 16/1/7. 19 | */ 20 | public class LoadView extends ImageView { 21 | private float degrees = 0f; 22 | private Matrix max; 23 | private int width; 24 | private int height; 25 | private Bitmap bitmap; 26 | 27 | public LoadView(Context context) { 28 | super(context); 29 | init(); 30 | } 31 | 32 | public LoadView(Context context, AttributeSet attrs) { 33 | super(context, attrs); 34 | init(); 35 | } 36 | 37 | public LoadView(Context context, AttributeSet attrs, int defStyleAttr) { 38 | super(context, attrs, defStyleAttr); 39 | init(); 40 | } 41 | 42 | Handler handler = new Handler() { 43 | @Override 44 | public void handleMessage(Message msg) { 45 | degrees += 30f; 46 | max.setRotate(degrees, width, height); 47 | setImageMatrix(max); 48 | if(degrees==360){ 49 | degrees=0; 50 | } 51 | } 52 | }; 53 | 54 | private void init() { 55 | setScaleType(ScaleType.MATRIX); 56 | bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.xlistview_loading); 57 | setImageBitmap(bitmap); 58 | max = new Matrix(); 59 | 60 | width = bitmap.getWidth() / 2; 61 | height = bitmap.getHeight() / 2; 62 | Timer time=new Timer(); 63 | time.schedule(new TimerTask() { 64 | @Override 65 | public void run() { 66 | handler.sendEmptyMessage(0); 67 | } 68 | },0,80); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/XListView/XListViewFooter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @file XFooterView.java 3 | * @create Mar 31, 2012 9:33:43 PM 4 | * @author Maxwin 5 | * @description XListView's footer 6 | */ 7 | package com.tellh.android_pulltorefreshlibrary_collection.XListView; 8 | 9 | import android.content.Context; 10 | import android.util.AttributeSet; 11 | import android.view.LayoutInflater; 12 | import android.view.View; 13 | import android.widget.LinearLayout; 14 | import android.widget.TextView; 15 | 16 | import com.tellh.android_pulltorefreshlibrary_collection.R; 17 | 18 | public class XListViewFooter extends LinearLayout { 19 | public final static int STATE_NORMAL = 0; 20 | public final static int STATE_READY = 1; 21 | public final static int STATE_LOADING = 2; 22 | 23 | private Context mContext; 24 | 25 | private View mContentView; 26 | private View mProgressBar; 27 | private TextView mHintView; 28 | 29 | public XListViewFooter(Context context) { 30 | super(context); 31 | initView(context); 32 | } 33 | 34 | public XListViewFooter(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | initView(context); 37 | } 38 | 39 | 40 | public void setState(int state) { 41 | mHintView.setVisibility(View.INVISIBLE); 42 | mProgressBar.setVisibility(View.INVISIBLE); 43 | mHintView.setVisibility(View.INVISIBLE); 44 | if (state == STATE_READY) { 45 | mHintView.setVisibility(View.VISIBLE); 46 | mHintView.setText(R.string.xlistview_footer_hint_ready); 47 | } else if (state == STATE_LOADING) { 48 | mProgressBar.setVisibility(View.VISIBLE); 49 | } else { 50 | mHintView.setVisibility(View.VISIBLE); 51 | mHintView.setText(R.string.xlistview_footer_hint_normal); 52 | } 53 | } 54 | 55 | public void setBottomMargin(int height) { 56 | if (height < 0) return ; 57 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 58 | lp.bottomMargin = height; 59 | mContentView.setLayoutParams(lp); 60 | } 61 | 62 | public int getBottomMargin() { 63 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 64 | return lp.bottomMargin; 65 | } 66 | 67 | 68 | /** 69 | * normal status 70 | */ 71 | public void normal() { 72 | mHintView.setVisibility(View.VISIBLE); 73 | mProgressBar.setVisibility(View.GONE); 74 | } 75 | 76 | 77 | /** 78 | * loading status 79 | */ 80 | public void loading() { 81 | mHintView.setVisibility(View.GONE); 82 | mProgressBar.setVisibility(View.VISIBLE); 83 | } 84 | 85 | /** 86 | * hide footer when disable pull load more 87 | */ 88 | public void hide() { 89 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 90 | lp.height = 0; 91 | mContentView.setLayoutParams(lp); 92 | } 93 | 94 | /** 95 | * show footer 96 | */ 97 | public void show() { 98 | LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); 99 | lp.height = LayoutParams.WRAP_CONTENT; 100 | mContentView.setLayoutParams(lp); 101 | } 102 | 103 | private void initView(Context context) { 104 | mContext = context; 105 | LinearLayout moreView = (LinearLayout)LayoutInflater.from(mContext).inflate(R.layout.xlistview_footer, null); 106 | addView(moreView); 107 | moreView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 108 | 109 | mContentView = moreView.findViewById(R.id.xlistview_footer_content); 110 | mProgressBar = moreView.findViewById(R.id.xlistview_footer_progressbar); 111 | mHintView = (TextView)moreView.findViewById(R.id.xlistview_footer_hint_textview); 112 | } 113 | 114 | 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/XListView/XListViewHeader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @file XListViewHeader.java 3 | * @create Apr 18, 2012 5:22:27 PM 4 | * @author Maxwin 5 | * @description XListView's header 6 | */ 7 | package com.tellh.android_pulltorefreshlibrary_collection.XListView; 8 | 9 | import android.content.Context; 10 | import android.util.AttributeSet; 11 | import android.view.Gravity; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.animation.Animation; 15 | import android.view.animation.RotateAnimation; 16 | import android.widget.ImageView; 17 | import android.widget.LinearLayout; 18 | import android.widget.ProgressBar; 19 | import android.widget.TextView; 20 | 21 | import com.tellh.android_pulltorefreshlibrary_collection.R; 22 | 23 | public class XListViewHeader extends LinearLayout { 24 | private LinearLayout mContainer; 25 | private ImageView mArrowImageView; 26 | private ProgressBar mProgressBar; 27 | private TextView mHintTextView; 28 | private int mState = STATE_NORMAL; 29 | 30 | private Animation mRotateUpAnim; 31 | private Animation mRotateDownAnim; 32 | 33 | private final int ROTATE_ANIM_DURATION = 180; 34 | 35 | public final static int STATE_NORMAL = 0; 36 | public final static int STATE_READY = 1; 37 | public final static int STATE_REFRESHING = 2; 38 | 39 | public XListViewHeader(Context context) { 40 | super(context); 41 | initView(context); 42 | } 43 | 44 | /** 45 | * @param context 46 | * @param attrs 47 | */ 48 | public XListViewHeader(Context context, AttributeSet attrs) { 49 | super(context, attrs); 50 | initView(context); 51 | } 52 | 53 | private void initView(Context context) { 54 | // 初始情况,设置下拉刷新view高度为0 55 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( 56 | LayoutParams.FILL_PARENT, 0); 57 | mContainer = (LinearLayout) LayoutInflater.from(context).inflate( 58 | R.layout.xlistview_header, null); 59 | addView(mContainer, lp); 60 | setGravity(Gravity.BOTTOM); 61 | 62 | mArrowImageView = (ImageView)findViewById(R.id.xlistview_header_arrow); 63 | mHintTextView = (TextView)findViewById(R.id.xlistview_header_hint_textview); 64 | mProgressBar = (ProgressBar)findViewById(R.id.xlistview_header_progressbar); 65 | 66 | mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, 67 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 68 | 0.5f); 69 | mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION); 70 | mRotateUpAnim.setFillAfter(true); 71 | mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, 72 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 73 | 0.5f); 74 | mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION); 75 | mRotateDownAnim.setFillAfter(true); 76 | } 77 | 78 | public void setState(int state) { 79 | if (state == mState) return ; 80 | 81 | if (state == STATE_REFRESHING) { // 显示进度 82 | mArrowImageView.clearAnimation(); 83 | mArrowImageView.setVisibility(View.INVISIBLE); 84 | mProgressBar.setVisibility(View.VISIBLE); 85 | } else { // 显示箭头图片 86 | mArrowImageView.setVisibility(View.VISIBLE); 87 | mProgressBar.setVisibility(View.INVISIBLE); 88 | } 89 | 90 | switch(state){ 91 | case STATE_NORMAL: 92 | if (mState == STATE_READY) { 93 | mArrowImageView.startAnimation(mRotateDownAnim); 94 | } 95 | if (mState == STATE_REFRESHING) { 96 | mArrowImageView.clearAnimation(); 97 | } 98 | mHintTextView.setText(R.string.xlistview_header_hint_normal); 99 | break; 100 | case STATE_READY: 101 | if (mState != STATE_READY) { 102 | mArrowImageView.clearAnimation(); 103 | mArrowImageView.startAnimation(mRotateUpAnim); 104 | mHintTextView.setText(R.string.xlistview_header_hint_ready); 105 | } 106 | break; 107 | case STATE_REFRESHING: 108 | mHintTextView.setText(R.string.xlistview_header_hint_loading); 109 | break; 110 | default: 111 | } 112 | 113 | mState = state; 114 | } 115 | 116 | public void setVisiableHeight(int height) { 117 | if (height < 0) 118 | height = 0; 119 | LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContainer 120 | .getLayoutParams(); 121 | lp.height = height; 122 | mContainer.setLayoutParams(lp); 123 | } 124 | 125 | public int getVisiableHeight() { 126 | return mContainer.getLayoutParams().height; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/XListViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection; 2 | 3 | 4 | import com.tellh.android_pulltorefreshlibrary_collection.XListView.XListView; 5 | 6 | public class XListViewActivity extends BaseActivity { 7 | 8 | 9 | @Override 10 | public int getLayoutId() { 11 | return R.layout.activity_xlistview; 12 | } 13 | 14 | @Override 15 | public void initView() { 16 | } 17 | 18 | 19 | @Override 20 | public void onBackPressed() { 21 | if (((XListView)listView).isPullRefreshing()){ 22 | ((XListView)listView).stopRefresh(); 23 | return; 24 | } 25 | super.onBackPressed(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/tellh/android_pulltorefreshlibrary_collection/util/Logger.java: -------------------------------------------------------------------------------- 1 | package com.tellh.android_pulltorefreshlibrary_collection.util; 2 | 3 | import android.text.TextUtils; 4 | 5 | public final class Logger { 6 | 7 | private static final String TAG = "TellH"; 8 | 9 | /** 10 | * Set true or false if you want read logs or not 11 | */ 12 | private static boolean logEnabled_d = true; 13 | private static boolean logEnabled_i = false; 14 | private static boolean logEnabled_e = false; 15 | 16 | private Logger() {} 17 | 18 | public static void d() { 19 | if (logEnabled_d) { 20 | android.util.Log.v(TAG, getLocation()); 21 | } 22 | } 23 | 24 | public static void d(String msg) { 25 | if (logEnabled_d) { 26 | android.util.Log.v(TAG, getLocation() + msg); 27 | } 28 | } 29 | 30 | public static void i(String msg) { 31 | if (logEnabled_i) { 32 | android.util.Log.i(TAG, getLocation() + msg); 33 | } 34 | } 35 | 36 | public static void i() { 37 | if (logEnabled_i) { 38 | android.util.Log.i(TAG, getLocation()); 39 | } 40 | } 41 | 42 | public static void e(String msg) { 43 | if (logEnabled_e) { 44 | android.util.Log.e(TAG, getLocation() + msg); 45 | } 46 | } 47 | 48 | public static void e(String msg, Throwable e) { 49 | if (logEnabled_e) { 50 | android.util.Log.e(TAG, getLocation() + msg, e); 51 | } 52 | } 53 | 54 | public static void e(Throwable e) { 55 | if (logEnabled_e) { 56 | android.util.Log.e(TAG, getLocation(), e); 57 | } 58 | } 59 | 60 | public static void e() { 61 | if (logEnabled_e) { 62 | android.util.Log.e(TAG, getLocation()); 63 | } 64 | } 65 | 66 | private static String getLocation() { 67 | final String className = Logger.class.getName(); 68 | final StackTraceElement[] traces = Thread.currentThread() 69 | .getStackTrace(); 70 | boolean found = false; 71 | 72 | for (StackTraceElement trace : traces) { 73 | try { 74 | if (found) { 75 | if (!trace.getClassName().startsWith(className)) { 76 | Class clazz = Class.forName(trace.getClassName()); 77 | return "[" + getClassName(clazz) + ":" 78 | + trace.getMethodName() + ":" 79 | + trace.getLineNumber() + "]: "; 80 | } 81 | } else if (trace.getClassName().startsWith(className)) { 82 | found = true; 83 | } 84 | } catch (ClassNotFoundException ignored) { 85 | } 86 | } 87 | 88 | return "[]: "; 89 | } 90 | 91 | private static String getClassName(Class clazz) { 92 | if (clazz != null) { 93 | if (!TextUtils.isEmpty(clazz.getSimpleName())) { 94 | return clazz.getSimpleName(); 95 | } 96 | 97 | return getClassName(clazz.getEnclosingClass()); 98 | } 99 | 100 | return ""; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check_circle_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-hdpi/ic_check_circle_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/water_drop_refresh_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-hdpi/water_drop_refresh_arrow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check_circle_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-mdpi/ic_check_circle_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check_circle_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-xhdpi/ic_check_circle_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check_circle_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-xxhdpi/ic_check_circle_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/xlistview_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-xxhdpi/xlistview_arrow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/xlistview_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-xxhdpi/xlistview_loading.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_check_circle_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable-xxxhdpi/ic_check_circle_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TellH/Android_PullToRefreshLibrary_Collection/321afab15c889cb3da0c798161357cb223f5379f/app/src/main/res/drawable/down_arrow.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_circle_refresh.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_jelly_refresh.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 |