├── LICENSE
├── PullToRefresh
├── .gitignore
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── import-summary.txt
├── pullToRefreshlibrary
│ ├── .gitignore
│ ├── build.gradle
│ ├── libs
│ │ └── gif.jar
│ ├── lint.xml
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── jingchen
│ │ │ └── pulltorefresh
│ │ │ ├── GifHeadView.java
│ │ │ ├── PullToRefreshLayout.java
│ │ │ ├── Pullable.java
│ │ │ ├── PullableExpandableListView.java
│ │ │ ├── PullableGridView.java
│ │ │ ├── PullableImageView.java
│ │ │ ├── PullableListView.java
│ │ │ ├── PullableRecyclerView.java
│ │ │ ├── PullableScrollView.java
│ │ │ ├── PullableTextView.java
│ │ │ ├── PullableWebView.java
│ │ │ ├── RecyclerWrapAdapter.java
│ │ │ ├── WrapRecyclerView.java
│ │ │ └── WrapperAdapter.java
│ │ ├── jniLibs
│ │ ├── armeabi-v7a
│ │ │ └── libgif.so
│ │ ├── armeabi
│ │ │ └── libgif.so
│ │ ├── mips
│ │ │ └── libgif.so
│ │ └── x86
│ │ │ └── libgif.so
│ │ └── res
│ │ ├── anim
│ │ ├── reverse_down_anim.xml
│ │ ├── reverse_up_anim.xml
│ │ └── rotating_anim.xml
│ │ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ ├── anim.gif
│ │ ├── ic_launcher.png
│ │ ├── load_failed.png
│ │ ├── load_succeed.png
│ │ ├── loading.png
│ │ ├── pull_icon_big.png
│ │ ├── pullup_icon_big.png
│ │ ├── refresh_failed.png
│ │ ├── refresh_succeed.png
│ │ └── refreshing.png
│ │ ├── layout
│ │ ├── gif_headview.xml
│ │ ├── listview.xml
│ │ ├── load_more.xml
│ │ └── refresh_head.xml
│ │ ├── values-v11
│ │ └── styles.xml
│ │ ├── values-v14
│ │ └── styles.xml
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── pullToRefreshsample
│ ├── .gitignore
│ ├── build.gradle
│ ├── lint.xml
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── gen
│ │ └── com
│ │ │ └── lynnchurch
│ │ │ └── pulltorefresh
│ │ │ ├── BuildConfig.java
│ │ │ ├── Manifest.java
│ │ │ └── R.java
│ │ ├── java
│ │ └── com
│ │ │ └── lynnchurch
│ │ │ └── pulltorefresh
│ │ │ ├── BaseAutoLoadMoreAdapter.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MyAdapter.java
│ │ │ ├── MyPullListener.java
│ │ │ ├── MyRecyclerAdapter.java
│ │ │ └── activity
│ │ │ ├── PullableExpandableListViewActivity.java
│ │ │ ├── PullableGifActivity.java
│ │ │ ├── PullableGridViewActivity.java
│ │ │ ├── PullableImageViewActivity.java
│ │ │ ├── PullableListViewActivity.java
│ │ │ ├── PullableRecyclerViewActivity.java
│ │ │ ├── PullableScrollViewActivity.java
│ │ │ ├── PullableTextViewActivity.java
│ │ │ └── PullableWebViewActivity.java
│ │ ├── main1.iml
│ │ └── res
│ │ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ ├── anim.gif
│ │ ├── h.jpg
│ │ ├── i.jpg
│ │ ├── ic_launcher.png
│ │ ├── j.jpg
│ │ ├── k.jpg
│ │ ├── l.jpg
│ │ ├── load_failed.png
│ │ ├── load_succeed.png
│ │ ├── loading.png
│ │ ├── m.jpg
│ │ ├── pull_icon_big.png
│ │ ├── pullup_icon_big.png
│ │ ├── refresh_failed.png
│ │ ├── refresh_succeed.png
│ │ └── refreshing.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── layout
│ │ ├── activity_expandablelistview.xml
│ │ ├── activity_gridview.xml
│ │ ├── activity_imageview.xml
│ │ ├── activity_listview.xml
│ │ ├── activity_main.xml
│ │ ├── activity_recyclerview.xml
│ │ ├── activity_scrollview.xml
│ │ ├── activity_textview.xml
│ │ ├── activity_webview.xml
│ │ ├── header.xml
│ │ ├── list_item_layout.xml
│ │ ├── loadmore.xml
│ │ └── recyclerview_list_item.xml
│ │ ├── values-sw600dp
│ │ └── dimens.xml
│ │ ├── values-sw720dp-land
│ │ └── dimens.xml
│ │ └── values
│ │ ├── color.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── settings.gradle
├── README.md
└── images
└── sample_picture.gif
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/PullToRefresh/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | .idea
3 | build
4 | local.properties
5 | .DS_Store
6 | captures
7 | *.iml
--------------------------------------------------------------------------------
/PullToRefresh/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:1.3.0'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/PullToRefresh/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/PullToRefresh/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Mar 08 11:37:29 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip
7 |
--------------------------------------------------------------------------------
/PullToRefresh/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/PullToRefresh/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/PullToRefresh/import-summary.txt:
--------------------------------------------------------------------------------
1 | ECLIPSE ANDROID PROJECT IMPORT SUMMARY
2 | ======================================
3 |
4 | Manifest Merging:
5 | -----------------
6 | Your project uses libraries that provide manifests, and your Eclipse
7 | project did not explicitly turn on manifest merging. In Android Gradle
8 | projects, manifests are always merged (meaning that contents from your
9 | libraries' manifests will be merged into the app manifest. If you had
10 | manually copied contents from library manifests into your app manifest
11 | you may need to remove these for the app to build correctly.
12 |
13 | Ignored Files:
14 | --------------
15 | The following files were *not* copied into the new Gradle project; you
16 | should evaluate whether these are still needed in your project and if
17 | so manually move them:
18 |
19 | From PullToRefresh-library:
20 | * proguard-project.txt
21 | From PullToRefresh-sample:
22 | * .idea\
23 | * .idea\.name
24 | * .idea\PullToRefresh-sample.iml
25 | * .idea\compiler.xml
26 | * .idea\copyright\
27 | * .idea\copyright\profiles_settings.xml
28 | * .idea\misc.xml
29 | * .idea\modules.xml
30 | * .idea\vcs.xml
31 | * .idea\workspace.xml
32 | * PullToRefresh-sample.iml
33 | * README.md
34 | * ic_launcher-web.png
35 | * import-summary.txt
36 | * proguard-project.txt
37 | * pullToRefreshlibrary\
38 | * pullToRefreshlibrary\build.gradle
39 | * pullToRefreshlibrary\libs\
40 | * pullToRefreshlibrary\libs\gif.jar
41 | * pullToRefreshlibrary\lint.xml
42 | * pullToRefreshlibrary\src\
43 | * pullToRefreshlibrary\src\main\
44 | * pullToRefreshlibrary\src\main\AndroidManifest.xml
45 | * pullToRefreshlibrary\src\main\java\
46 | * pullToRefreshlibrary\src\main\java\com\
47 | * pullToRefreshlibrary\src\main\java\com\jingchen\
48 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\
49 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\GifHeadView.java
50 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullToRefreshLayout.java
51 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\Pullable.java
52 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableExpandableListView.java
53 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableGridView.java
54 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableImageView.java
55 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableListView.java
56 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableRecyclerView.java
57 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableScrollView.java
58 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableTextView.java
59 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\PullableWebView.java
60 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\RecyclerWrapAdapter.java
61 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\WrapRecyclerView.java
62 | * pullToRefreshlibrary\src\main\java\com\jingchen\pulltorefresh\WrapperAdapter.java
63 | * pullToRefreshlibrary\src\main\jniLibs\
64 | * pullToRefreshlibrary\src\main\jniLibs\armeabi-v7a\
65 | * pullToRefreshlibrary\src\main\jniLibs\armeabi-v7a\libgif.so
66 | * pullToRefreshlibrary\src\main\jniLibs\armeabi\
67 | * pullToRefreshlibrary\src\main\jniLibs\armeabi\libgif.so
68 | * pullToRefreshlibrary\src\main\jniLibs\mips\
69 | * pullToRefreshlibrary\src\main\jniLibs\mips\libgif.so
70 | * pullToRefreshlibrary\src\main\jniLibs\x86\
71 | * pullToRefreshlibrary\src\main\jniLibs\x86\libgif.so
72 | * pullToRefreshlibrary\src\main\res\
73 | * pullToRefreshlibrary\src\main\res\anim\
74 | * pullToRefreshlibrary\src\main\res\anim\reverse_down_anim.xml
75 | * pullToRefreshlibrary\src\main\res\anim\reverse_up_anim.xml
76 | * pullToRefreshlibrary\src\main\res\anim\rotating_anim.xml
77 | * pullToRefreshlibrary\src\main\res\drawable-hdpi\
78 | * pullToRefreshlibrary\src\main\res\drawable-hdpi\ic_launcher.png
79 | * pullToRefreshlibrary\src\main\res\drawable-mdpi\
80 | * pullToRefreshlibrary\src\main\res\drawable-mdpi\ic_launcher.png
81 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\
82 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\anim.gif
83 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\ic_launcher.png
84 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\load_failed.png
85 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\load_succeed.png
86 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\loading.png
87 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\pull_icon_big.png
88 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\pullup_icon_big.png
89 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\refresh_failed.png
90 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\refresh_succeed.png
91 | * pullToRefreshlibrary\src\main\res\drawable-xhdpi\refreshing.png
92 | * pullToRefreshlibrary\src\main\res\layout\
93 | * pullToRefreshlibrary\src\main\res\layout\gif_headview.xml
94 | * pullToRefreshlibrary\src\main\res\layout\listview.xml
95 | * pullToRefreshlibrary\src\main\res\layout\load_more.xml
96 | * pullToRefreshlibrary\src\main\res\layout\refresh_head.xml
97 | * pullToRefreshlibrary\src\main\res\values-v11\
98 | * pullToRefreshlibrary\src\main\res\values-v11\styles.xml
99 | * pullToRefreshlibrary\src\main\res\values-v14\
100 | * pullToRefreshlibrary\src\main\res\values-v14\styles.xml
101 | * pullToRefreshlibrary\src\main\res\values\
102 | * pullToRefreshlibrary\src\main\res\values\attrs.xml
103 | * pullToRefreshlibrary\src\main\res\values\colors.xml
104 | * pullToRefreshlibrary\src\main\res\values\dimens.xml
105 | * pullToRefreshlibrary\src\main\res\values\strings.xml
106 | * pullToRefreshlibrary\src\main\res\values\styles.xml
107 | * screenshots\
108 | * screenshots\ExpandableListView.gif
109 | * screenshots\GridView.gif
110 | * screenshots\ImageView.gif
111 | * screenshots\ListView.gif
112 | * screenshots\ScrollView.gif
113 | * screenshots\TextView.gif
114 | * screenshots\WebView.gif
115 | * screenshots\main.gif
116 | * settings.gradle
117 |
118 | Replaced Jars with Dependencies:
119 | --------------------------------
120 | The importer recognized the following .jar files as third party
121 | libraries and replaced them with Gradle dependencies instead. This has
122 | the advantage that more explicit version information is known, and the
123 | libraries can be updated automatically. However, it is possible that
124 | the .jar file in your project was of an older version than the
125 | dependency we picked, which could render the project not compileable.
126 | You can disable the jar replacement in the import wizard and try again:
127 |
128 | android-support-v4.jar => com.android.support:support-v4:19.1.0
129 |
130 | Moved Files:
131 | ------------
132 | Android Gradle projects use a different directory structure than ADT
133 | Eclipse projects. Here's how the projects were restructured:
134 |
135 | In PullToRefresh-library:
136 | * AndroidManifest.xml => pullToRefreshlibrary\src\main\AndroidManifest.xml
137 | * libs\armeabi-v7a\libgif.so => pullToRefreshlibrary\src\main\jniLibs\armeabi-v7a\libgif.so
138 | * libs\armeabi\libgif.so => pullToRefreshlibrary\src\main\jniLibs\armeabi\libgif.so
139 | * libs\gif.jar => pullToRefreshlibrary\libs\gif.jar
140 | * libs\mips\libgif.so => pullToRefreshlibrary\src\main\jniLibs\mips\libgif.so
141 | * libs\x86\libgif.so => pullToRefreshlibrary\src\main\jniLibs\x86\libgif.so
142 | * lint.xml => pullToRefreshlibrary\lint.xml
143 | * res\ => pullToRefreshlibrary\src\main\res\
144 | * src\ => pullToRefreshlibrary\src\main\java\
145 | In PullToRefresh-sample:
146 | * AndroidManifest.xml => pullToRefreshsample\src\main\AndroidManifest.xml
147 | * lint.xml => pullToRefreshsample\lint.xml
148 | * res\ => pullToRefreshsample\src\main\res\
149 | * src\ => pullToRefreshsample\src\main\java\
150 |
151 | Next Steps:
152 | -----------
153 | You can now build the project. The Gradle project needs network
154 | connectivity to download dependencies.
155 |
156 | Bugs:
157 | -----
158 | If for some reason your project does not build, and you determine that
159 | it is due to a bug or limitation of the Eclipse to Gradle importer,
160 | please file a bug at http://b.android.com with category
161 | Component-Tools.
162 |
163 | (This import summary is for your information only, and can be deleted
164 | after import once you are satisfied with the results.)
165 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | minSdkVersion 14
9 | targetSdkVersion 23
10 | }
11 |
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
16 | }
17 | }
18 | }
19 |
20 | dependencies {
21 | compile files('libs/gif.jar')
22 | compile 'com.android.support:recyclerview-v7:21.+'
23 | compile 'com.android.support:cardview-v7:21.+'
24 | }
25 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/libs/gif.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/libs/gif.jar
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
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 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/GifHeadView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import pl.droidsonroids.gif.GifDrawable;
4 | import pl.droidsonroids.gif.GifImageView;
5 | import android.content.Context;
6 | import android.util.AttributeSet;
7 | import android.view.LayoutInflater;
8 | import android.widget.RelativeLayout;
9 |
10 | public class GifHeadView extends RelativeLayout
11 | {
12 | private GifImageView gifImageView;
13 |
14 | public GifHeadView(Context context)
15 | {
16 | this(context, null, 0);
17 | // TODO Auto-generated constructor stub
18 | }
19 |
20 | public GifHeadView(Context context, AttributeSet attrs)
21 | {
22 | this(context, attrs, 0);
23 | // TODO Auto-generated constructor stub
24 | }
25 |
26 | public GifHeadView(Context context, AttributeSet attrs, int defStyleAttr)
27 | {
28 | super(context, attrs, defStyleAttr);
29 | // TODO Auto-generated constructor stub
30 | LayoutInflater.from(context).inflate(R.layout.gif_headview, this, true);
31 | gifImageView = (GifImageView) findViewById(R.id.giv_anim);
32 | }
33 |
34 | /**
35 | * 设置gif动画资源
36 | *
37 | * @param gifDrawable
38 | */
39 | public void setGifAnim(GifDrawable gifDrawable)
40 | {
41 | gifImageView.setImageDrawable(gifDrawable);
42 | // 停止自动播放
43 | gifDrawable.stop();
44 | }
45 |
46 | /**
47 | * 获取gif
48 | *
49 | * @return
50 | */
51 | public GifDrawable getDrawable()
52 | {
53 | return (GifDrawable) gifImageView.getDrawable();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullToRefreshLayout.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.os.AsyncTask;
5 | import android.os.Handler;
6 | import android.os.Message;
7 | import android.util.AttributeSet;
8 | import android.view.LayoutInflater;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 | import android.view.animation.AnimationUtils;
12 | import android.view.animation.LinearInterpolator;
13 | import android.view.animation.RotateAnimation;
14 | import android.widget.RelativeLayout;
15 | import android.widget.TextView;
16 |
17 | import java.lang.ref.WeakReference;
18 | import java.util.Timer;
19 | import java.util.TimerTask;
20 |
21 | import pl.droidsonroids.gif.GifDrawable;
22 |
23 | /**
24 | * 自定义的布局,用来管理三个子控件,其中一个是下拉头,一个是包含内容的pullableView(可以是实现Pullable接口的的任何View),
25 | * 还有一个上拉头,更多详解见博客http://blog.csdn.net/zhongkejingwang/article/details/38868463
26 | *
27 | * @author 陈靖
28 | */
29 | public class PullToRefreshLayout extends RelativeLayout
30 | {
31 | public static final String TAG = "PullToRefreshLayout";
32 | // 初始状态
33 | public static final int INIT = 0;
34 | // 释放刷新
35 | public static final int RELEASE_TO_REFRESH = 1;
36 | // 正在刷新
37 | public static final int REFRESHING = 2;
38 | // 释放加载
39 | public static final int RELEASE_TO_LOAD = 3;
40 | // 正在加载
41 | public static final int LOADING = 4;
42 | // 操作完毕
43 | public static final int DONE = 5;
44 | // 当前状态
45 | private int state = INIT;
46 | // 刷新回调接口
47 | private OnPullListener mListener;
48 | // 刷新成功
49 | public static final int SUCCEED = 0;
50 | // 刷新失败
51 | public static final int FAIL = 1;
52 | // 按下Y坐标,上一个事件点Y坐标
53 | private float downY, lastY;
54 |
55 | // 下拉的距离。注意:pullDownY和pullUpY不可能同时不为0
56 | public float pullDownY = 0;
57 | // 上拉的距离
58 | private float pullUpY = 0;
59 |
60 | // 释放刷新的距离
61 | private float refreshDist = 200;
62 | // 释放加载的距离
63 | private float loadmoreDist = 200;
64 |
65 | private MyTimer timer;
66 | // 回滚速度
67 | public float mMoveSpeed = 8;
68 | // 第一次执行布局
69 | private boolean isLayout = false;
70 | // 在刷新过程中滑动操作
71 | private boolean isTouch = false;
72 | // 手指滑动距离与下拉头的滑动距离比,中间会随正切函数变化
73 | private float radio = 2;
74 |
75 | // 下拉箭头的转180°动画
76 | private RotateAnimation reverseUpAnimation;
77 | private RotateAnimation reverseDownAnimation;
78 | // 均匀旋转动画
79 | private RotateAnimation refreshingAnimation;
80 |
81 | // 默认下拉头
82 | private View defaultRefreshView;
83 | // 下拉的箭头
84 | private View pullDownView;
85 | // 正在刷新的图标
86 | private View refreshingView;
87 | // 刷新结果图标
88 | private View refreshStateImageView;
89 | // 刷新结果:成功或失败
90 | private TextView refreshStateTextView;
91 |
92 | // 默认上拉头
93 | private View defaultLoadmoreView;
94 | // // 上拉的箭头
95 | private View pullUpView;
96 | // 正在加载的图标
97 | private View loadingView;
98 | // 加载结果图标
99 | private View loadStateImageView;
100 | // 加载结果:成功或失败
101 | private TextView loadStateTextView;
102 |
103 | // 实现了Pullable接口的View
104 | private View pullableView;
105 | // 过滤多点触碰
106 | private int mEvents;
107 | // 这两个变量用来控制pull的方向,如果不加控制,当情况满足可上拉又可下拉时没法下拉
108 | private boolean mCanPullDown = true;
109 | private boolean mCanPullUp = true;
110 |
111 | private boolean mPullDownEnable = true;
112 | private boolean mPullUpEnable = true;
113 |
114 | // 执行自动回滚的handler
115 | private Handler updateHandler;
116 |
117 | // 自定义下拉头
118 | private View customRefreshView;
119 | // 自定义上拉头
120 | private View customLoadmoreView;
121 | // 下拉刷新过程监听器
122 | private OnPullProcessListener mOnRefreshProcessListener;
123 | // 上拉加载更多过程监听器
124 | private OnPullProcessListener mOnLoadmoreProcessListener;
125 |
126 | // 下拉头
127 | private View refreshView;
128 | // 上拉头
129 | private View loadmoreView;
130 |
131 | // 是否已经准备下拉
132 | private boolean mPreparedPullDown;
133 | // 是否已经准备上拉
134 | private boolean mPreparedPullUp;
135 |
136 | public PullToRefreshLayout(Context context)
137 | {
138 | this(context, null, 0);
139 | }
140 |
141 | public PullToRefreshLayout(Context context, AttributeSet attrs)
142 | {
143 | this(context, attrs, 0);
144 | }
145 |
146 | public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle)
147 | {
148 | super(context, attrs, defStyle);
149 | initView(context, attrs, defStyle);
150 | }
151 |
152 | private void initView(Context context, AttributeSet attrs, int defStyle)
153 | {
154 | updateHandler = new UpdateHandler(this);
155 | timer = new MyTimer(updateHandler);
156 | reverseUpAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
157 | context, R.anim.reverse_up_anim);
158 | reverseDownAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
159 | context, R.anim.reverse_down_anim);
160 | refreshingAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
161 | context, R.anim.rotating_anim);
162 | // 添加匀速转动动画
163 | LinearInterpolator lir = new LinearInterpolator();
164 | reverseUpAnimation.setInterpolator(lir);
165 | refreshingAnimation.setInterpolator(lir);
166 |
167 | // 添加上拉头和下拉头
168 | LayoutInflater inflater = LayoutInflater.from(context);
169 | defaultRefreshView = inflater.inflate(R.layout.refresh_head, this,
170 | false);
171 | refreshView = defaultRefreshView;
172 | defaultLoadmoreView = inflater.inflate(R.layout.load_more, this, false);
173 | loadmoreView = defaultLoadmoreView;
174 | addView(defaultRefreshView);
175 | addView(defaultLoadmoreView);
176 | }
177 |
178 | /**
179 | * 获取可拉取的视图
180 | *
181 | * @return
182 | */
183 | public View getPullableView()
184 | {
185 | for (int i = 0; i < getChildCount(); i++)
186 | {
187 | View v = getChildAt(i);
188 | if (v instanceof Pullable)
189 | {
190 | pullableView = v;
191 | return pullableView;
192 | }
193 | }
194 | return pullableView;
195 | }
196 |
197 | /**
198 | * 设置自定义下拉头
199 | *
200 | * @param v
201 | */
202 | public void setCustomRefreshView(View v)
203 | {
204 | customRefreshView = v;
205 | removeView(defaultRefreshView);
206 | addView(customRefreshView);
207 | refreshView = customRefreshView;
208 | }
209 |
210 | /**
211 | * 设置自定义上拉头
212 | *
213 | * @param v
214 | */
215 | public void setCustomLoadmoreView(View v)
216 | {
217 | customLoadmoreView = v;
218 | removeView(defaultLoadmoreView);
219 | addView(customLoadmoreView);
220 | loadmoreView = customLoadmoreView;
221 | }
222 |
223 | /**
224 | * 设置下拉刷新gif动画头
225 | *
226 | * @param headGifDrawable
227 | */
228 | public void setGifRefreshView(GifDrawable headGifDrawable)
229 | {
230 | // 设置下拉头
231 | GifHeadView headView = new GifHeadView(getContext());
232 | headView.setGifAnim(headGifDrawable);
233 | setCustomRefreshView(headView);
234 | setOnRefreshProcessListener(new GifOnPullProcessListener(
235 | headView.getDrawable()));
236 | }
237 |
238 | /**
239 | * 设置上拉加载更多gif动画头
240 | *
241 | * @param footGifDrawable
242 | */
243 | public void setGifLoadmoreView(GifDrawable footGifDrawable)
244 | {
245 | // 设置上拉头
246 | GifHeadView footView = new GifHeadView(getContext());
247 | footView.setGifAnim(footGifDrawable);
248 | setCustomLoadmoreView(footView);
249 | setOnLoadmoreProcessListener(new GifOnPullProcessListener(
250 | footView.getDrawable()));
251 | }
252 |
253 | private void hide()
254 | {
255 | timer.schedule(5);
256 | }
257 |
258 | /**
259 | * 完成刷新操作,显示刷新结果。注意:刷新完成后一定要调用这个方法
260 | */
261 | /**
262 | * @param refreshResult PullToRefreshLayout.SUCCEED代表成功,PullToRefreshLayout.FAIL代表失败
263 | */
264 | public void refreshFinish(final int refreshResult)
265 | {
266 | new Handler().postDelayed(new Runnable()
267 | {
268 | @Override
269 | public void run()
270 | {
271 | if (null != mOnRefreshProcessListener)
272 | {
273 | mOnRefreshProcessListener.onFinish(refreshView,
274 | OnPullProcessListener.REFRESH);
275 | }
276 | if (null == customRefreshView)
277 | {
278 | refreshingView.clearAnimation();
279 | refreshingView.setVisibility(View.GONE);
280 | }
281 | switch (refreshResult)
282 | {
283 | case SUCCEED:
284 | // 刷新成功
285 | if (null == customRefreshView)
286 | {
287 | refreshStateImageView.setVisibility(View.VISIBLE);
288 | refreshStateTextView.setText(R.string.refresh_succeed);
289 | refreshStateImageView
290 | .setBackgroundResource(R.drawable.refresh_succeed);
291 | }
292 | break;
293 | case FAIL:
294 | default:
295 | // 刷新失败
296 | if (null == customRefreshView)
297 | {
298 | refreshStateImageView.setVisibility(View.VISIBLE);
299 | refreshStateTextView.setText(R.string.refresh_fail);
300 | refreshStateImageView
301 | .setBackgroundResource(R.drawable.refresh_failed);
302 | }
303 | break;
304 | }
305 | if (pullDownY > 0)
306 | {
307 | // 刷新结果停留1秒
308 | new RemainHandler(PullToRefreshLayout.this).sendEmptyMessageDelayed(0, 1000);
309 | } else
310 | {
311 | changeState(DONE);
312 | hide();
313 | }
314 | }
315 | }, 2400);
316 | }
317 |
318 | /**
319 | * 加载完毕,显示加载结果。注意:加载完成后一定要调用这个方法
320 | *
321 | * @param refreshResult PullToRefreshLayout.SUCCEED代表成功,PullToRefreshLayout.FAIL代表失败
322 | */
323 | public void loadmoreFinish(int refreshResult)
324 | {
325 | if (null != mOnLoadmoreProcessListener)
326 | {
327 | mOnLoadmoreProcessListener.onFinish(loadmoreView,
328 | OnPullProcessListener.LOADMORE);
329 | }
330 | if (null == customLoadmoreView)
331 | {
332 | loadingView.clearAnimation();
333 | loadingView.setVisibility(View.GONE);
334 | }
335 |
336 | switch (refreshResult)
337 | {
338 | case SUCCEED:
339 | // 加载成功
340 | if (null == customLoadmoreView)
341 | {
342 | loadStateImageView.setVisibility(View.VISIBLE);
343 | loadStateTextView.setText(R.string.load_succeed);
344 | loadStateImageView
345 | .setBackgroundResource(R.drawable.load_succeed);
346 | }
347 | break;
348 | case FAIL:
349 | default:
350 | // 加载失败
351 | if (null == customLoadmoreView)
352 | {
353 | loadStateImageView.setVisibility(View.VISIBLE);
354 | loadStateTextView.setText(R.string.load_fail);
355 | loadStateImageView
356 | .setBackgroundResource(R.drawable.load_failed);
357 | }
358 | break;
359 | }
360 | if (pullUpY < 0)
361 | {
362 | // 刷新结果停留1秒
363 | new RemainHandler(this).sendEmptyMessageDelayed(0, 1000);
364 | } else
365 | {
366 | changeState(DONE);
367 | hide();
368 | }
369 | }
370 |
371 | private void changeState(int to)
372 | {
373 | state = to;
374 | switch (state)
375 | {
376 | case INIT:
377 | mPreparedPullDown = false;
378 | mPreparedPullUp = false;
379 | // 下拉布局初始状态
380 | if (null == customRefreshView)
381 | {
382 | pullDownView.startAnimation(reverseDownAnimation);
383 | refreshStateImageView.setVisibility(View.GONE);
384 | refreshStateTextView.setText(R.string.pull_to_refresh);
385 | pullDownView.setVisibility(View.VISIBLE);
386 | }
387 | // 上拉布局初始状态
388 | if (null == customLoadmoreView)
389 | {
390 | pullUpView.startAnimation(reverseDownAnimation);
391 | loadStateImageView.setVisibility(View.GONE);
392 | loadStateTextView.setText(R.string.pullup_to_load);
393 | pullUpView.setVisibility(View.VISIBLE);
394 | }
395 | break;
396 | case RELEASE_TO_REFRESH:
397 | if (null != mOnRefreshProcessListener)
398 | {
399 | mOnRefreshProcessListener.onStart(refreshView,
400 | OnPullProcessListener.REFRESH);
401 | }
402 | // 释放刷新状态
403 | if (null == customRefreshView)
404 | {
405 | refreshStateTextView.setText(R.string.release_to_refresh);
406 | pullDownView.startAnimation(reverseUpAnimation);
407 | }
408 | break;
409 | case REFRESHING:
410 | if (null != mOnRefreshProcessListener)
411 | {
412 | mOnRefreshProcessListener.onHandling(refreshView,
413 | OnPullProcessListener.REFRESH);
414 | }
415 | // 正在刷新状态
416 | if (null == customRefreshView)
417 | {
418 | pullDownView.clearAnimation();
419 | refreshingView.setVisibility(View.VISIBLE);
420 | pullDownView.setVisibility(View.INVISIBLE);
421 | refreshingView.startAnimation(refreshingAnimation);
422 | refreshStateTextView.setText(R.string.refreshing);
423 | }
424 | break;
425 | case RELEASE_TO_LOAD:
426 | if (null != mOnLoadmoreProcessListener)
427 | {
428 | mOnLoadmoreProcessListener.onStart(loadmoreView,
429 | OnPullProcessListener.LOADMORE);
430 | }
431 | // 释放加载状态
432 | if (null == customLoadmoreView)
433 | {
434 | loadStateTextView.setText(R.string.release_to_load);
435 | pullUpView.startAnimation(reverseUpAnimation);
436 | }
437 | break;
438 | case LOADING:
439 | // 正在加载状态
440 | if (null != mOnLoadmoreProcessListener)
441 | {
442 | mOnLoadmoreProcessListener.onHandling(loadmoreView,
443 | OnPullProcessListener.LOADMORE);
444 | }
445 | if (null == customLoadmoreView)
446 | {
447 | pullUpView.clearAnimation();
448 | loadingView.setVisibility(View.VISIBLE);
449 | pullUpView.setVisibility(View.INVISIBLE);
450 | loadingView.startAnimation(refreshingAnimation);
451 | loadStateTextView.setText(R.string.loading);
452 | } else
453 | {
454 | customLoadmoreView.setVisibility(View.VISIBLE);
455 | }
456 | break;
457 | case DONE:
458 | refreshView.setVisibility(View.VISIBLE);
459 | loadmoreView.setVisibility(View.VISIBLE);
460 | break;
461 | }
462 | }
463 |
464 | /**
465 | * 不限制上拉或下拉
466 | */
467 | private void releasePull()
468 | {
469 | mCanPullDown = true;
470 | mCanPullUp = true;
471 | }
472 |
473 | /**
474 | * 设置是否可下拉刷新
475 | *
476 | * @param pullDownEnable
477 | */
478 | public void setPullDownEnable(boolean pullDownEnable)
479 | {
480 | mPullDownEnable = pullDownEnable;
481 | }
482 |
483 | /**
484 | * 设置是否可上拉刷新
485 | */
486 | public void setPullUpEnable(boolean pullUpEnable)
487 | {
488 | mPullUpEnable = pullUpEnable;
489 | }
490 |
491 | /*
492 | * (非 Javadoc)由父控件决定是否分发事件,防止事件冲突
493 | *
494 | * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
495 | */
496 | @Override
497 | public boolean dispatchTouchEvent(MotionEvent ev)
498 | {
499 | switch (ev.getActionMasked())
500 | {
501 | case MotionEvent.ACTION_DOWN:
502 | downY = ev.getY();
503 | lastY = downY;
504 | timer.cancel();
505 | mEvents = 0;
506 | releasePull();
507 | break;
508 | case MotionEvent.ACTION_POINTER_DOWN:
509 | case MotionEvent.ACTION_POINTER_UP:
510 | // 过滤多点触碰
511 | mEvents = -1;
512 | break;
513 | case MotionEvent.ACTION_MOVE:
514 | if (null != mOnRefreshProcessListener && pullDownY > 0)
515 | {
516 | if (!mPreparedPullDown)
517 | {
518 | mPreparedPullDown = true;
519 | if (null != mOnRefreshProcessListener)
520 | {
521 | mOnRefreshProcessListener.onPrepare(refreshView,
522 | OnPullProcessListener.REFRESH);
523 | }
524 | }
525 | mOnRefreshProcessListener.onPull(refreshView, pullDownY,
526 | OnPullProcessListener.REFRESH);
527 | }
528 | if (null != mOnLoadmoreProcessListener && pullUpY < 0)
529 | {
530 | if (!mPreparedPullUp)
531 | {
532 | mPreparedPullUp = true;
533 | if (null != mOnLoadmoreProcessListener)
534 | {
535 | mOnLoadmoreProcessListener.onPrepare(loadmoreView,
536 | OnPullProcessListener.LOADMORE);
537 | }
538 | }
539 | mOnLoadmoreProcessListener.onPull(loadmoreView, pullUpY,
540 | OnPullProcessListener.LOADMORE);
541 | }
542 | if (mEvents == 0)
543 | {
544 | if (pullDownY > 0
545 | || (((Pullable) pullableView).canPullDown()
546 | && mCanPullDown && mPullDownEnable && state != LOADING))
547 | {
548 | // 可以下拉,正在加载时不能下拉
549 | // 对实际滑动距离做缩小,造成用力拉的感觉
550 | pullDownY = pullDownY + (ev.getY() - lastY) / radio;
551 | if (pullDownY < 0)
552 | {
553 | pullDownY = 0;
554 | mCanPullDown = false;
555 | mCanPullUp = true;
556 | }
557 | if (pullDownY > getMeasuredHeight())
558 | pullDownY = getMeasuredHeight();
559 | if (state == REFRESHING)
560 | {
561 | // 正在刷新的时候触摸移动
562 | isTouch = true;
563 | }
564 | } else if (pullUpY < 0
565 | || (((Pullable) pullableView).canPullUp() && mCanPullUp
566 | && mPullUpEnable && state != REFRESHING))
567 | {
568 | // 可以上拉,正在刷新时不能上拉
569 | pullUpY = pullUpY + (ev.getY() - lastY) / radio;
570 | if (pullUpY > 0)
571 | {
572 | pullUpY = 0;
573 | mCanPullDown = true;
574 | mCanPullUp = false;
575 | }
576 | if (pullUpY < -getMeasuredHeight())
577 | pullUpY = -getMeasuredHeight();
578 | if (state == LOADING)
579 | {
580 | // 正在加载的时候触摸移动
581 | isTouch = true;
582 | }
583 | } else
584 | releasePull();
585 | } else
586 | mEvents = 0;
587 | lastY = ev.getY();
588 | // 根据下拉距离改变比例
589 | radio = (float) (2 + 2 * Math.tan(Math.PI / 2 / getMeasuredHeight()
590 | * (pullDownY + Math.abs(pullUpY))));
591 | if (pullDownY > 0 || pullUpY < 0)
592 | requestLayout();
593 | if (pullDownY > 0)
594 | {
595 | if (pullDownY <= refreshDist
596 | && (state == RELEASE_TO_REFRESH || state == DONE))
597 | {
598 | // 如果下拉距离没达到刷新的距离且当前状态是释放刷新,改变状态为下拉刷新
599 | changeState(INIT);
600 | }
601 | if (pullDownY >= refreshDist && state == INIT)
602 | {
603 | // 如果下拉距离达到刷新的距离且当前状态是初始状态刷新,改变状态为释放刷新
604 | changeState(RELEASE_TO_REFRESH);
605 | }
606 | } else if (pullUpY < 0)
607 | {
608 | // 下面是判断上拉加载的,同上,注意pullUpY是负值
609 | if (-pullUpY <= loadmoreDist
610 | && (state == RELEASE_TO_LOAD || state == DONE))
611 | {
612 | changeState(INIT);
613 | }
614 | // 上拉操作
615 | if (-pullUpY >= loadmoreDist && state == INIT)
616 | {
617 | changeState(RELEASE_TO_LOAD);
618 | }
619 |
620 | }
621 | // 因为刷新和加载操作不能同时进行,所以pullDownY和pullUpY不会同时不为0,因此这里用(pullDownY +
622 | // Math.abs(pullUpY))就可以不对当前状态作区分了
623 | if ((pullDownY + Math.abs(pullUpY)) > 8)
624 | {
625 | // 防止下拉过程中误触发长按事件和点击事件
626 | ev.setAction(MotionEvent.ACTION_CANCEL);
627 | }
628 | break;
629 | case MotionEvent.ACTION_UP:
630 | if (pullDownY > refreshDist || -pullUpY > loadmoreDist)
631 | // 正在刷新时往下拉(正在加载时往上拉),释放后下拉头(上拉头)不隐藏
632 | {
633 | isTouch = false;
634 | }
635 | if (state == RELEASE_TO_REFRESH)
636 | {
637 | changeState(REFRESHING);
638 | // 刷新操作
639 | if (mListener != null)
640 | mListener.onRefresh(this);
641 | } else if (state == RELEASE_TO_LOAD)
642 | {
643 | changeState(LOADING);
644 | // 加载操作
645 | if (mListener != null)
646 | mListener.onLoadMore(this);
647 | }
648 | hide();
649 | default:
650 | break;
651 | }
652 | // 事件分发交给父类
653 | super.dispatchTouchEvent(ev);
654 | return true;
655 | }
656 |
657 | /**
658 | * @author chenjing 自动模拟手指滑动的task
659 | */
660 | private class AutoRefreshAndLoadTask extends
661 | AsyncTask
662 | {
663 |
664 | @Override
665 | protected String doInBackground(Integer... params)
666 | {
667 | while (pullDownY < 4 / 3 * refreshDist)
668 | {
669 | pullDownY += mMoveSpeed;
670 | publishProgress(pullDownY);
671 | try
672 | {
673 | Thread.sleep(params[0]);
674 | } catch (InterruptedException e)
675 | {
676 | e.printStackTrace();
677 | }
678 | }
679 | return null;
680 | }
681 |
682 | @Override
683 | protected void onPostExecute(String result)
684 | {
685 | changeState(REFRESHING);
686 | // 刷新操作
687 | if (mListener != null)
688 | mListener.onRefresh(PullToRefreshLayout.this);
689 | if (null != mOnRefreshProcessListener)
690 | {
691 | mOnRefreshProcessListener.onStart(refreshView,
692 | OnPullProcessListener.REFRESH);
693 | }
694 | hide();
695 | }
696 |
697 | @Override
698 | protected void onProgressUpdate(Float... values)
699 | {
700 | if (pullDownY > refreshDist)
701 | changeState(RELEASE_TO_REFRESH);
702 | requestLayout();
703 | }
704 |
705 | }
706 |
707 | /**
708 | * 自动刷新
709 | */
710 | public void autoRefresh()
711 | {
712 | loadmoreView.setVisibility(View.GONE);
713 | AutoRefreshAndLoadTask task = new AutoRefreshAndLoadTask();
714 | task.execute(2);
715 | }
716 |
717 | /**
718 | * 自动加载
719 | */
720 | public void autoLoad()
721 | {
722 | refreshView.setVisibility(View.GONE);
723 | pullUpY = -loadmoreDist;
724 | requestLayout();
725 | changeState(LOADING);
726 | // 加载操作
727 | if (mListener != null)
728 | mListener.onLoadMore(this);
729 | }
730 |
731 | private void initView()
732 | {
733 | // 初始化下拉布局
734 | if (null == customRefreshView)
735 | {
736 | pullDownView = defaultRefreshView.findViewById(R.id.pull_icon);
737 | refreshStateTextView = (TextView) defaultRefreshView
738 | .findViewById(R.id.state_tv);
739 | refreshingView = defaultRefreshView
740 | .findViewById(R.id.refreshing_icon);
741 | refreshStateImageView = defaultRefreshView
742 | .findViewById(R.id.state_iv);
743 | }
744 | // 初始化上拉布局
745 | if (null == customLoadmoreView)
746 | {
747 | pullUpView = defaultLoadmoreView.findViewById(R.id.pullup_icon);
748 | loadStateTextView = (TextView) defaultLoadmoreView
749 | .findViewById(R.id.loadstate_tv);
750 | loadingView = defaultLoadmoreView.findViewById(R.id.loading_icon);
751 | loadStateImageView = defaultLoadmoreView
752 | .findViewById(R.id.loadstate_iv);
753 | }
754 | }
755 |
756 | @Override
757 | protected void onLayout(boolean changed, int l, int t, int r, int b)
758 | {
759 | if (!isLayout)
760 | {
761 | // 这里是第一次进来的时候做一些初始化
762 | getPullableView();
763 | isLayout = true;
764 | initView();
765 | refreshView.measure(0, 0);
766 | refreshDist = refreshView.getMeasuredHeight();
767 | loadmoreView.measure(0, 0);
768 | loadmoreDist = loadmoreView.getMeasuredHeight();
769 | }
770 | // 改变子控件的布局,这里直接用(pullDownY + pullUpY)作为偏移量,这样就可以不对当前状态作区分
771 | refreshView.layout(0,
772 | (int) (pullDownY + pullUpY) - refreshView.getMeasuredHeight(),
773 | refreshView.getMeasuredWidth(), (int) (pullDownY + pullUpY));
774 | pullableView.layout(0, (int) (pullDownY + pullUpY),
775 | pullableView.getMeasuredWidth(), (int) (pullDownY + pullUpY)
776 | + pullableView.getMeasuredHeight());
777 | loadmoreView.layout(0,
778 | (int) (pullDownY + pullUpY) + pullableView.getMeasuredHeight(),
779 | loadmoreView.getMeasuredWidth(),
780 | (int) (pullDownY + pullUpY) + pullableView.getMeasuredHeight()
781 | + loadmoreView.getMeasuredHeight());
782 | }
783 |
784 | class MyTimer
785 | {
786 | private Handler handler;
787 | private Timer timer;
788 | private MyTask mTask;
789 |
790 | public MyTimer(Handler handler)
791 | {
792 | this.handler = handler;
793 | timer = new Timer();
794 | }
795 |
796 | public void schedule(long period)
797 | {
798 | if (mTask != null)
799 | {
800 | mTask.cancel();
801 | mTask = null;
802 | }
803 | mTask = new MyTask(handler);
804 | timer.schedule(mTask, 0, period);
805 | }
806 |
807 | public void cancel()
808 | {
809 | if (mTask != null)
810 | {
811 | mTask.cancel();
812 | mTask = null;
813 | }
814 | }
815 |
816 | class MyTask extends TimerTask
817 | {
818 | private Handler handler;
819 |
820 | public MyTask(Handler handler)
821 | {
822 | this.handler = handler;
823 | }
824 |
825 | @Override
826 | public void run()
827 | {
828 | handler.obtainMessage().sendToTarget();
829 | }
830 |
831 | }
832 | }
833 |
834 | /**
835 | * 刷新结果停留的handler
836 | */
837 | static class RemainHandler extends Handler
838 | {
839 | private WeakReference mLayout;
840 |
841 | public RemainHandler(PullToRefreshLayout layout)
842 | {
843 | mLayout = new WeakReference<>(layout);
844 | }
845 |
846 | @Override
847 | public void handleMessage(Message msg)
848 | {
849 | PullToRefreshLayout layout = mLayout.get();
850 | if (null != layout)
851 | {
852 | layout.changeState(DONE);
853 | layout.hide();
854 | }
855 | }
856 | }
857 |
858 | /**
859 | * 执行自动回滚的handler
860 | */
861 | static class UpdateHandler extends Handler
862 | {
863 | private WeakReference mLayout;
864 |
865 | public UpdateHandler(PullToRefreshLayout layout)
866 | {
867 | mLayout = new WeakReference<>(layout);
868 | }
869 |
870 | @Override
871 | public void handleMessage(Message msg)
872 | {
873 | PullToRefreshLayout layout = mLayout.get();
874 | if (null != layout)
875 | {
876 | // 回弹速度随下拉距离moveDeltaY增大而增大
877 | layout.mMoveSpeed = (float) (8 + 5 * Math.tan(Math.PI / 2
878 | / layout.getMeasuredHeight()
879 | * (layout.pullDownY + Math.abs(layout.pullUpY))));
880 | if (!layout.isTouch)
881 | {
882 | // 正在刷新,且没有往上推的话则悬停,显示"正在刷新..."
883 | if (layout.state == REFRESHING
884 | && layout.pullDownY <= layout.refreshDist)
885 | {
886 | layout.pullDownY = layout.refreshDist;
887 | layout.timer.cancel();
888 | } else if (layout.state == LOADING
889 | && -layout.pullUpY <= layout.loadmoreDist)
890 | {
891 | layout.pullUpY = -layout.loadmoreDist;
892 | layout.timer.cancel();
893 | }
894 |
895 | }
896 | if (layout.pullDownY > 0)
897 | layout.pullDownY -= layout.mMoveSpeed;
898 | else if (layout.pullUpY < 0)
899 | layout.pullUpY += layout.mMoveSpeed;
900 | if (layout.pullDownY < 0)
901 | {
902 | // 已完成回弹
903 | layout.pullDownY = 0;
904 | if (null == layout.customRefreshView)
905 | {
906 | layout.pullDownView.clearAnimation();
907 | }
908 | // 隐藏下拉头时有可能还在刷新,只有当前状态不是正在刷新时才改变状态
909 | if (layout.state != REFRESHING && layout.state != LOADING)
910 | layout.changeState(INIT);
911 | layout.timer.cancel();
912 | layout.requestLayout();
913 | }
914 | if (layout.pullUpY > 0)
915 | {
916 | // 已完成回弹
917 | layout.pullUpY = 0;
918 | if (null == layout.customLoadmoreView)
919 | {
920 | layout.pullUpView.clearAnimation();
921 | }
922 | // 隐藏上拉头时有可能还在刷新,只有当前状态不是正在刷新时才改变状态
923 | if (layout.state != REFRESHING && layout.state != LOADING)
924 | layout.changeState(INIT);
925 | layout.timer.cancel();
926 | layout.requestLayout();
927 | }
928 | // 刷新布局,会自动调用onLayout
929 | layout.requestLayout();
930 | // 没有拖拉或者回弹完成
931 | if (layout.pullDownY + Math.abs(layout.pullUpY) == 0)
932 | layout.timer.cancel();
933 | }
934 | }
935 |
936 | }
937 |
938 | ;
939 |
940 | public void setOnPullListener(OnPullListener listener)
941 | {
942 | mListener = listener;
943 | }
944 |
945 | /**
946 | * 设置下拉刷新过程监听器
947 | *
948 | * @param onPullProcessListener
949 | */
950 | public void setOnRefreshProcessListener(
951 | OnPullProcessListener onPullProcessListener)
952 | {
953 | mOnRefreshProcessListener = onPullProcessListener;
954 | }
955 |
956 | /**
957 | * 设置上拉加载更多过程监听器
958 | *
959 | * @param onPullProcessListener
960 | */
961 | public void setOnLoadmoreProcessListener(
962 | OnPullProcessListener onPullProcessListener)
963 | {
964 | mOnLoadmoreProcessListener = onPullProcessListener;
965 | }
966 |
967 | /**
968 | * 刷新加载回调接口
969 | *
970 | * @author chenjing
971 | */
972 | public interface OnPullListener
973 | {
974 | /**
975 | * 刷新操作
976 | */
977 | void onRefresh(PullToRefreshLayout pullToRefreshLayout);
978 |
979 | /**
980 | * 加载操作
981 | */
982 | void onLoadMore(PullToRefreshLayout pullToRefreshLayout);
983 | }
984 |
985 | /**
986 | * 下拉刷新或上拉加载更多过程监听器
987 | *
988 | * @author LynnChurch
989 | */
990 | public interface OnPullProcessListener
991 | {
992 | int REFRESH = 1; // 刷新
993 |
994 | int LOADMORE = 2; // 加载更多
995 |
996 | /**
997 | * 准备 (提示下拉刷新或上拉加载更多)
998 | *
999 | * @param v
1000 | * @param which 刷新或加载更多
1001 | */
1002 | void onPrepare(View v, int which);
1003 |
1004 | /**
1005 | * 开始 (提示释放刷新或释放加载更多)
1006 | *
1007 | * @param v
1008 | * @param which 刷新或加载更多
1009 | */
1010 | void onStart(View v, int which);
1011 |
1012 | /**
1013 | * 处理中
1014 | *
1015 | * @param v
1016 | * @param which 刷新或加载更多
1017 | */
1018 | void onHandling(View v, int which);
1019 |
1020 | /**
1021 | * 完成
1022 | *
1023 | * @param v
1024 | * @param which 刷新或加载更多
1025 | */
1026 | void onFinish(View v, int which);
1027 |
1028 | /**
1029 | * 用于获取拉取的距离
1030 | *
1031 | * @param v
1032 | * @param pullDistance
1033 | * @param which 刷新或加载更多
1034 | */
1035 | void onPull(View v, float pullDistance, int which);
1036 | }
1037 |
1038 | /**
1039 | * 用于gif动画的控制
1040 | *
1041 | * @author LynnChurch
1042 | */
1043 | public class GifOnPullProcessListener implements OnPullProcessListener
1044 | {
1045 | private GifDrawable mGifDrawable;
1046 | private int lastFramePosition; // 上一帧的位置
1047 |
1048 | public GifOnPullProcessListener(GifDrawable gifDrawable)
1049 | {
1050 | mGifDrawable = gifDrawable;
1051 | }
1052 |
1053 | @Override
1054 | public void onPrepare(View v, int which)
1055 | {
1056 | // TODO Auto-generated method stub
1057 | mGifDrawable.stop();
1058 | }
1059 |
1060 | @Override
1061 | public void onStart(View v, int which)
1062 | {
1063 | // TODO Auto-generated method stub
1064 | }
1065 |
1066 | @Override
1067 | public void onHandling(View v, int which)
1068 | {
1069 | // TODO Auto-generated method stub
1070 | mGifDrawable.start();
1071 | }
1072 |
1073 | @Override
1074 | public void onFinish(View v, int which)
1075 | {
1076 | // TODO Auto-generated method stub
1077 | mGifDrawable.stop();
1078 | }
1079 |
1080 | @Override
1081 | public void onPull(View v, float pullDistance, int which)
1082 | {
1083 | // TODO Auto-generated method stub
1084 | // 动画总帧数
1085 | int frames = mGifDrawable.getNumberOfFrames();
1086 | RelativeLayout headView = (RelativeLayout) v
1087 | .findViewById(R.id.head_view);
1088 | int headViewHeight = headView.getHeight();
1089 | // 算出下拉过程中对应的动画进度
1090 | float progress = Math.abs(pullDistance % headViewHeight
1091 | / headViewHeight);
1092 | // 当前播放帧
1093 | int currentFrame = (int) (frames * progress) + 1;
1094 |
1095 | // 当前帧与上一帧不同时才进行播放,保证流畅度
1096 | if (lastFramePosition != currentFrame)
1097 | {
1098 | // 需要进行动画重置,否则不能够自由地定位到每一帧
1099 | mGifDrawable.reset();
1100 | mGifDrawable.seekToFrame(currentFrame);
1101 | lastFramePosition = currentFrame;
1102 | }
1103 | }
1104 |
1105 | }
1106 | }
1107 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/Pullable.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | public interface Pullable
4 | {
5 | /**
6 | * 判断是否可以下拉,如果不需要下拉功能可以直接return false
7 | *
8 | * @return true如果可以下拉否则返回false
9 | */
10 | boolean canPullDown();
11 |
12 | /**
13 | * 判断是否可以上拉,如果不需要上拉功能可以直接return false
14 | *
15 | * @return true如果可以上拉否则返回false
16 | */
17 | boolean canPullUp();
18 | }
19 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableExpandableListView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ExpandableListView;
6 |
7 | public class PullableExpandableListView extends ExpandableListView implements
8 | Pullable
9 | {
10 |
11 | public PullableExpandableListView(Context context)
12 | {
13 | super(context);
14 | }
15 |
16 | public PullableExpandableListView(Context context, AttributeSet attrs)
17 | {
18 | super(context, attrs);
19 | }
20 |
21 | public PullableExpandableListView(Context context, AttributeSet attrs,
22 | int defStyle)
23 | {
24 | super(context, attrs, defStyle);
25 | }
26 |
27 | @Override
28 | public boolean canPullDown()
29 | {
30 | if (getCount() == 0)
31 | {
32 | // 没有item的时候也可以下拉刷新
33 | return true;
34 | } else if (getFirstVisiblePosition() == 0
35 | && getChildAt(0).getTop() >= 0)
36 | {
37 | // 滑到顶部了
38 | return true;
39 | } else
40 | return false;
41 | }
42 |
43 | @Override
44 | public boolean canPullUp()
45 | {
46 | if (getCount() == 0)
47 | {
48 | // 没有item的时候也可以上拉加载
49 | return true;
50 | } else if (getLastVisiblePosition() == (getCount() - 1))
51 | {
52 | // 滑到底部了
53 | if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
54 | && getChildAt(
55 | getLastVisiblePosition()
56 | - getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
57 | return true;
58 | }
59 | return false;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableGridView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.GridView;
6 |
7 | public class PullableGridView extends GridView implements Pullable
8 | {
9 |
10 | public PullableGridView(Context context)
11 | {
12 | super(context);
13 | }
14 |
15 | public PullableGridView(Context context, AttributeSet attrs)
16 | {
17 | super(context, attrs);
18 | }
19 |
20 | public PullableGridView(Context context, AttributeSet attrs, int defStyle)
21 | {
22 | super(context, attrs, defStyle);
23 | }
24 |
25 | @Override
26 | public boolean canPullDown()
27 | {
28 | if (getCount() == 0)
29 | {
30 | // 没有item的时候也可以下拉刷新
31 | return true;
32 | } else if (getFirstVisiblePosition() == 0
33 | && getChildAt(0).getTop() >= 0)
34 | {
35 | // 滑到顶部了
36 | return true;
37 | } else
38 | return false;
39 | }
40 |
41 | @Override
42 | public boolean canPullUp()
43 | {
44 | if (getCount() == 0)
45 | {
46 | // 没有item的时候也可以上拉加载
47 | return true;
48 | } else if (getLastVisiblePosition() == (getCount() - 1))
49 | {
50 | // 滑到底部了
51 | if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
52 | && getChildAt(
53 | getLastVisiblePosition()
54 | - getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
55 | return true;
56 | }
57 | return false;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableImageView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ImageView;
6 |
7 |
8 | public class PullableImageView extends ImageView implements Pullable
9 | {
10 |
11 | public PullableImageView(Context context)
12 | {
13 | super(context);
14 | }
15 |
16 | public PullableImageView(Context context, AttributeSet attrs)
17 | {
18 | super(context, attrs);
19 | }
20 |
21 | public PullableImageView(Context context, AttributeSet attrs, int defStyle)
22 | {
23 | super(context, attrs, defStyle);
24 | }
25 |
26 | @Override
27 | public boolean canPullDown()
28 | {
29 | return true;
30 | }
31 |
32 | @Override
33 | public boolean canPullUp()
34 | {
35 | return true;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableListView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ListView;
6 |
7 | public class PullableListView extends ListView implements Pullable
8 | {
9 |
10 | public PullableListView(Context context)
11 | {
12 | super(context);
13 | }
14 |
15 | public PullableListView(Context context, AttributeSet attrs)
16 | {
17 | super(context, attrs);
18 | }
19 |
20 | public PullableListView(Context context, AttributeSet attrs, int defStyle)
21 | {
22 | super(context, attrs, defStyle);
23 | }
24 |
25 | @Override
26 | public boolean canPullDown()
27 | {
28 | if (getCount() == 0)
29 | {
30 | // 没有item的时候也可以下拉刷新
31 | return true;
32 | } else if (getFirstVisiblePosition() == 0
33 | && getChildAt(0).getTop() >= 0)
34 | {
35 | // 滑到ListView的顶部了
36 | return true;
37 | } else
38 | return false;
39 | }
40 |
41 | @Override
42 | public boolean canPullUp()
43 | {
44 | if (getCount() == 0)
45 | {
46 | // 没有item的时候也可以上拉加载
47 | return true;
48 | } else if (getLastVisiblePosition() == (getCount() - 1))
49 | {
50 | // 滑到底部了
51 | if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
52 | && getChildAt(
53 | getLastVisiblePosition()
54 | - getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
55 | return true;
56 | }
57 | return false;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.GridLayoutManager;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.support.v7.widget.StaggeredGridLayoutManager;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 |
11 |
12 | public class PullableRecyclerView extends WrapRecyclerView implements Pullable
13 | {
14 | public static final String TAG = PullableRecyclerView.class.getSimpleName();
15 | public int mFirstVisiblePosition = -1;
16 | public int mLastVisiblePosition = -1;
17 | private OnScrollUpListener mOnScrollUpListener;
18 | private int mTempLastVisiblePosition = -1;
19 |
20 | public PullableRecyclerView(Context context)
21 | {
22 | this(context, null, 0);
23 | }
24 |
25 | public PullableRecyclerView(Context context, AttributeSet attrs)
26 | {
27 | this(context, attrs, 0);
28 | }
29 |
30 | public PullableRecyclerView(Context context, AttributeSet attrs, int defStyle)
31 | {
32 | super(context, attrs, defStyle);
33 | setOnScrollListener(new OnScrollListener()
34 | {
35 | @Override
36 | public void onScrolled(RecyclerView recyclerView, int dx, int dy)
37 | {
38 | if (null != mOnScrollUpListener)
39 | {
40 | // Log.i(TAG, "LastVisibleItemPosition:" + getLastVisibleItemPosition());
41 | // Log.i(TAG, "position:" + mTempLastVisiblePosition);
42 | // Log.i(TAG, "childCount:" + getChildCount());
43 | if (getAdapter().getItemCount() - 1 == getLastVisibleItemPosition())
44 | {
45 | return;
46 | }
47 | if (mTempLastVisiblePosition < getLastVisibleItemPosition()
48 | || mTempLastVisiblePosition - getLastVisibleItemPosition() >= getChildCount())
49 | {
50 | mTempLastVisiblePosition = getLastVisibleItemPosition();
51 | mOnScrollUpListener.onScrollUp(mTempLastVisiblePosition);
52 | }
53 | }
54 | }
55 | });
56 | }
57 |
58 | @Override
59 | public boolean canPullDown()
60 | {
61 | LayoutManager lm = getLayoutManager();
62 | mFirstVisiblePosition = getFirstVisibleItemPosition();
63 | View view = lm.findViewByPosition(mFirstVisiblePosition);
64 | int count = getAdapter().getItemCount();
65 | if (0 == count)
66 | {
67 | // 没有item的时候也可以下拉刷新
68 | return true;
69 | } else if (null != view && view.getTop() == 0 && mFirstVisiblePosition == 0)
70 | {
71 | // 滑到ListView的顶部了
72 | return true;
73 | } else
74 | return false;
75 | }
76 |
77 | @Override
78 | public boolean canPullUp()
79 | {
80 | LayoutManager lm = getLayoutManager();
81 | mFirstVisiblePosition = getFirstVisibleItemPosition();
82 | mLastVisiblePosition = getLastVisibleItemPosition();
83 | int count = getAdapter().getItemCount();
84 | if (0 == count)
85 | {
86 | // 没有item的时候也可以上拉加载
87 | return true;
88 | } else if (mLastVisiblePosition == (count - 1))
89 | {
90 | // 滑到底部了
91 | if (lm.findViewByPosition(count - 1).getBottom() <= getMeasuredHeight())
92 | {
93 | return true;
94 | }
95 | }
96 | return false;
97 | }
98 |
99 |
100 | /**
101 | * 获取顶部可见项的位置
102 | *
103 | * @return
104 | */
105 | public int getFirstVisibleItemPosition()
106 | {
107 | LayoutManager lm = getLayoutManager();
108 | int firstVisibleItemPosition = 0;
109 | if (lm instanceof GridLayoutManager)
110 | {
111 | firstVisibleItemPosition = ((GridLayoutManager) lm).findFirstVisibleItemPosition();
112 | } else if (lm instanceof LinearLayoutManager)
113 | {
114 | firstVisibleItemPosition = ((LinearLayoutManager) lm).findFirstVisibleItemPosition();
115 | } else if (lm instanceof StaggeredGridLayoutManager)
116 | {
117 | int positions[] = new int[1];
118 | ((StaggeredGridLayoutManager) lm).findFirstVisibleItemPositions(positions);
119 | firstVisibleItemPosition = positions[0];
120 | }
121 | return firstVisibleItemPosition;
122 | }
123 |
124 | /**
125 | * 获取底部可见项的位置
126 | *
127 | * @return
128 | */
129 | public int getLastVisibleItemPosition()
130 | {
131 | LayoutManager lm = getLayoutManager();
132 | int lastVisibleItemPosition = 0;
133 | if (lm instanceof GridLayoutManager)
134 | {
135 | lastVisibleItemPosition = ((GridLayoutManager) lm).findLastVisibleItemPosition();
136 | } else if (lm instanceof LinearLayoutManager)
137 | {
138 | lastVisibleItemPosition = ((LinearLayoutManager) lm).findLastVisibleItemPosition();
139 | } else if (lm instanceof StaggeredGridLayoutManager)
140 | {
141 | int positions[] = new int[1];
142 | ((StaggeredGridLayoutManager) lm).findLastVisibleItemPositions(positions);
143 | lastVisibleItemPosition = positions[0];
144 | }
145 | return lastVisibleItemPosition;
146 | }
147 |
148 | public int getFirstVisiblePosition()
149 | {
150 | return mFirstVisiblePosition;
151 | }
152 |
153 | public int getLastVisiblePosition()
154 | {
155 | return mLastVisiblePosition;
156 | }
157 |
158 | public void setOnScrollUpListener(OnScrollUpListener listener)
159 | {
160 | mOnScrollUpListener = listener;
161 | }
162 |
163 | /**
164 | * 向上滚动监听
165 | */
166 | public interface OnScrollUpListener
167 | {
168 | void onScrollUp(int position);
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableScrollView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ScrollView;
6 |
7 | public class PullableScrollView extends ScrollView implements Pullable
8 | {
9 |
10 | public PullableScrollView(Context context)
11 | {
12 | super(context);
13 | }
14 |
15 | public PullableScrollView(Context context, AttributeSet attrs)
16 | {
17 | super(context, attrs);
18 | }
19 |
20 | public PullableScrollView(Context context, AttributeSet attrs, int defStyle)
21 | {
22 | super(context, attrs, defStyle);
23 | }
24 |
25 | @Override
26 | public boolean canPullDown()
27 | {
28 | if (getScrollY() == 0)
29 | return true;
30 | else
31 | return false;
32 | }
33 |
34 | @Override
35 | public boolean canPullUp()
36 | {
37 | if (getScrollY() >= (getChildAt(0).getHeight() - getMeasuredHeight()))
38 | return true;
39 | else
40 | return false;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableTextView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 |
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.widget.TextView;
7 |
8 | public class PullableTextView extends TextView implements Pullable
9 | {
10 |
11 | public PullableTextView(Context context)
12 | {
13 | super(context);
14 | }
15 |
16 | public PullableTextView(Context context, AttributeSet attrs)
17 | {
18 | super(context, attrs);
19 | }
20 |
21 | public PullableTextView(Context context, AttributeSet attrs, int defStyle)
22 | {
23 | super(context, attrs, defStyle);
24 | }
25 |
26 | @Override
27 | public boolean canPullDown()
28 | {
29 | return true;
30 | }
31 |
32 | @Override
33 | public boolean canPullUp()
34 | {
35 | return true;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/PullableWebView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.webkit.WebView;
6 |
7 | public class PullableWebView extends WebView implements Pullable
8 | {
9 |
10 | public PullableWebView(Context context)
11 | {
12 | super(context);
13 | }
14 |
15 | public PullableWebView(Context context, AttributeSet attrs)
16 | {
17 | super(context, attrs);
18 | }
19 |
20 | public PullableWebView(Context context, AttributeSet attrs, int defStyle)
21 | {
22 | super(context, attrs, defStyle);
23 | }
24 |
25 | @Override
26 | public boolean canPullDown()
27 | {
28 | if (getScrollY() == 0)
29 | return true;
30 | else
31 | return false;
32 | }
33 |
34 | @Override
35 | public boolean canPullUp()
36 | {
37 | if (getScrollY() >= getContentHeight() * getScale()
38 | - getMeasuredHeight())
39 | return true;
40 | else
41 | return false;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/RecyclerWrapAdapter.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 |
7 | import java.util.ArrayList;
8 |
9 | public class RecyclerWrapAdapter extends RecyclerView.Adapter implements WrapperAdapter
10 | {
11 |
12 | private RecyclerView.Adapter mAdapter;
13 |
14 | private ArrayList mHeaderViews;
15 |
16 | private ArrayList mFootViews;
17 |
18 | static final ArrayList EMPTY_INFO_LIST =
19 | new ArrayList<>();
20 |
21 |
22 | public RecyclerWrapAdapter(ArrayList headerViews, ArrayList footViews, RecyclerView.Adapter adapter)
23 | {
24 | mAdapter = adapter;
25 | if (null == headerViews)
26 | {
27 | mHeaderViews = EMPTY_INFO_LIST;
28 | } else
29 | {
30 | mHeaderViews = headerViews;
31 | }
32 | if (null == footViews)
33 | {
34 | mFootViews = EMPTY_INFO_LIST;
35 | } else
36 | {
37 | mFootViews = footViews;
38 | }
39 | }
40 |
41 | public int getHeadersCount()
42 | {
43 | return mHeaderViews.size();
44 | }
45 |
46 | public int getFootersCount()
47 | {
48 | return mFootViews.size();
49 | }
50 |
51 | @Override
52 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
53 | {
54 | if (viewType == RecyclerView.INVALID_TYPE)
55 | {
56 | mHeaderViews.get(0).setLayoutParams(parent.getLayoutParams());
57 | return new HeaderViewHolder(mHeaderViews.get(0));
58 | } else if (viewType == RecyclerView.INVALID_TYPE - 1)
59 | {
60 | mFootViews.get(0).setLayoutParams(parent.getLayoutParams());
61 | return new HeaderViewHolder(mFootViews.get(0));
62 | }
63 | return mAdapter.onCreateViewHolder(parent, viewType);
64 | }
65 |
66 | @Override
67 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
68 | {
69 | int numHeaders = getHeadersCount();
70 | if (position < numHeaders)
71 | {
72 | return;
73 | }
74 | int adjPosition = position - numHeaders;
75 | int adapterCount = 0;
76 | if (mAdapter != null)
77 | {
78 | adapterCount = mAdapter.getItemCount();
79 | if (adjPosition < adapterCount)
80 | {
81 | mAdapter.onBindViewHolder(holder, adjPosition);
82 | return;
83 | }
84 | }
85 | }
86 |
87 | @Override
88 | public int getItemCount()
89 | {
90 | if (mAdapter != null)
91 | {
92 | return getHeadersCount() + getFootersCount() + mAdapter.getItemCount();
93 | } else
94 | {
95 | return getHeadersCount() + getFootersCount();
96 | }
97 | }
98 |
99 | @Override
100 | public int getItemViewType(int position)
101 | {
102 | int numHeaders = getHeadersCount();
103 | if (position < numHeaders)
104 | {
105 | return RecyclerView.INVALID_TYPE;
106 | }
107 | int adjPosition = position - numHeaders;
108 | int adapterCount = 0;
109 | if (mAdapter != null)
110 | {
111 | adapterCount = mAdapter.getItemCount();
112 | if (adjPosition < adapterCount)
113 | {
114 | return mAdapter.getItemViewType(adjPosition);
115 | }
116 | }
117 | return RecyclerView.INVALID_TYPE - 1;
118 | }
119 |
120 |
121 | @Override
122 | public long getItemId(int position)
123 | {
124 | int numHeaders = getHeadersCount();
125 | if (mAdapter != null && position >= numHeaders)
126 | {
127 | int adjPosition = position - numHeaders;
128 | int adapterCount = mAdapter.getItemCount();
129 | if (adjPosition < adapterCount)
130 | {
131 | return mAdapter.getItemId(adjPosition);
132 | }
133 | }
134 | return -1;
135 | }
136 |
137 |
138 | @Override
139 | public RecyclerView.Adapter getWrappedAdapter()
140 | {
141 | return mAdapter;
142 | }
143 |
144 | private static class HeaderViewHolder extends RecyclerView.ViewHolder
145 | {
146 | public HeaderViewHolder(View itemView)
147 | {
148 | super(itemView);
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/WrapRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.util.AttributeSet;
6 | import android.view.View;
7 |
8 | import java.util.ArrayList;
9 |
10 | public class WrapRecyclerView extends RecyclerView
11 | {
12 |
13 | private ArrayList mHeaderViews = new ArrayList<>();
14 |
15 | private ArrayList mFootViews = new ArrayList<>();
16 |
17 | private Adapter mAdapter;
18 |
19 | public WrapRecyclerView(Context context)
20 | {
21 | super(context);
22 | }
23 |
24 | public WrapRecyclerView(Context context, AttributeSet attrs)
25 | {
26 | super(context, attrs);
27 | }
28 |
29 | public WrapRecyclerView(Context context, AttributeSet attrs, int defStyle)
30 | {
31 | super(context, attrs, defStyle);
32 | }
33 |
34 | public void addHeaderView(View view)
35 | {
36 | mHeaderViews.clear();
37 | mHeaderViews.add(view);
38 | if (mAdapter != null)
39 | {
40 | if (!(mAdapter instanceof RecyclerWrapAdapter))
41 | {
42 | mAdapter = new RecyclerWrapAdapter(mHeaderViews, mFootViews, mAdapter);
43 | mAdapter.notifyDataSetChanged();
44 | }
45 | }
46 | }
47 |
48 | public void addFootView(View view)
49 | {
50 | mFootViews.clear();
51 | mFootViews.add(view);
52 | if (mAdapter != null)
53 | {
54 | if (!(mAdapter instanceof RecyclerWrapAdapter))
55 | {
56 | mAdapter = new RecyclerWrapAdapter(mHeaderViews, mFootViews, mAdapter);
57 | mAdapter.notifyDataSetChanged();
58 | }
59 | }
60 | }
61 |
62 | @Override
63 | public void setAdapter(Adapter adapter)
64 | {
65 |
66 | if (mHeaderViews.isEmpty() && mFootViews.isEmpty())
67 | {
68 | super.setAdapter(adapter);
69 | } else
70 | {
71 | adapter = new RecyclerWrapAdapter(mHeaderViews, mFootViews, adapter);
72 | super.setAdapter(adapter);
73 | }
74 | mAdapter = adapter;
75 | }
76 |
77 | /**
78 | * 获取页眉的高度
79 | *
80 | * @return
81 | */
82 | public int getHeaderHeight()
83 | {
84 | int height = 0;
85 | if (!mHeaderViews.isEmpty())
86 | {
87 | for (int i = 0; i < mHeaderViews.size(); i++)
88 | {
89 | mHeaderViews.get(i).measure(0, 0);
90 | height += mHeaderViews.get(i).getHeight();
91 | }
92 | }
93 | return height;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/java/com/jingchen/pulltorefresh/WrapperAdapter.java:
--------------------------------------------------------------------------------
1 | package com.jingchen.pulltorefresh;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 |
5 | public interface WrapperAdapter
6 | {
7 |
8 | public RecyclerView.Adapter getWrappedAdapter();
9 | }
10 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/armeabi-v7a/libgif.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/armeabi-v7a/libgif.so
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/armeabi/libgif.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/armeabi/libgif.so
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/mips/libgif.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/mips/libgif.so
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/x86/libgif.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/jniLibs/x86/libgif.so
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/anim/reverse_down_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/anim/reverse_up_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/anim/rotating_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/anim.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/anim.gif
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/load_failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/load_failed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/load_succeed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/load_succeed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/loading.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/pull_icon_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/pull_icon_big.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/pullup_icon_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/pullup_icon_big.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/refresh_failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/refresh_failed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/refresh_succeed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/refresh_succeed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/refreshing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshlibrary/src/main/res/drawable-xhdpi/refreshing.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/layout/gif_headview.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/layout/listview.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/layout/load_more.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
19 |
20 |
27 |
28 |
36 |
37 |
45 |
46 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/layout/refresh_head.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
19 |
20 |
27 |
28 |
36 |
37 |
45 |
46 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #000000
5 | #AAAA
6 |
7 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 通用版下拉刷新上拉加载控件
5 | 这里是HeadView
6 | 下拉刷新
7 | 释放立即刷新
8 | 正在刷新...
9 | 刷新成功
10 | 刷新失败
11 | 上拉加载更多
12 | 释放立即加载
13 | 正在加载...
14 | 加载成功
15 | 加载失败
16 |
17 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshlibrary/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/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.jingchen.pulltorefresh"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | }
12 |
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile project(':pullToRefreshlibrary')
23 | compile 'com.lsjwzh:materialloadingprogressbar:0.5.8-RELEASE'
24 | }
25 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
13 |
14 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
33 |
36 |
39 |
42 |
45 |
48 |
51 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/gen/com/lynnchurch/pulltorefresh/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.lynnchurch.pulltorefresh;
4 |
5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
6 | public final class BuildConfig {
7 | public final static boolean DEBUG = Boolean.parseBoolean(null);
8 | }
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/gen/com/lynnchurch/pulltorefresh/Manifest.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.lynnchurch.pulltorefresh;
4 |
5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
6 | public final class Manifest {
7 | }
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/gen/com/lynnchurch/pulltorefresh/R.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.lynnchurch.pulltorefresh;
4 |
5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
6 | public final class R {
7 | }
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/BaseAutoLoadMoreAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 | import com.jingchen.pulltorefresh.WrapRecyclerView;
11 | import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar;
12 |
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * 自动加载更多适配器
17 | */
18 | public abstract class BaseAutoLoadMoreAdapter extends RecyclerView.Adapter
19 | {
20 | private static final String TAG = BaseAutoLoadMoreAdapter.class.getSimpleName();
21 | protected Context mContext;
22 | protected ArrayList mData;
23 | private OnItemClickListener mOnItemClickListener;
24 | private OnLoadmoreListener mOnLoadmoreListener;
25 | private int mLastPosition; // 正常项最后一项的位置
26 | private WrapRecyclerView mParentView;
27 | private int mParentHeight; // item父视图的高度
28 | private int mItemsHeight; // 所有item的总高度
29 | private TextView tv_hint;
30 | private CircleProgressBar progressBar;
31 |
32 |
33 | public BaseAutoLoadMoreAdapter(Context context, WrapRecyclerView recyclerView, ArrayList data)
34 | {
35 | mContext = context;
36 | mParentView = recyclerView;
37 | initFooter(recyclerView);
38 | mData = data;
39 | mLastPosition = mData.size() - 1;
40 | }
41 |
42 | private void initFooter(WrapRecyclerView recyclerView)
43 | {
44 | View footer = LayoutInflater.from(mContext).inflate(R.layout.loadmore, null);
45 | tv_hint = (TextView) footer.findViewById(R.id.tv_hint);
46 | progressBar = (CircleProgressBar) footer.findViewById(R.id.progressBar);
47 | recyclerView.addFootView(footer);
48 | showLoading(false);
49 | }
50 |
51 | @Override
52 | final public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
53 | {
54 | mParentHeight = parent.getHeight();
55 | return onCreateBaseViewHolder(parent, viewType);
56 | }
57 |
58 | public abstract BaseViewHolder onCreateBaseViewHolder(ViewGroup parent, int viewType);
59 |
60 | public abstract int getItemHeight(RecyclerView.ViewHolder holder);
61 |
62 | public void resetItemHeight()
63 | {
64 | mItemsHeight = 0;
65 | }
66 |
67 | @Override
68 | final public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position)
69 | {
70 | if(!isOverParent())
71 | {
72 | showLoading(false);
73 | mItemsHeight+=getItemHeight(holder);
74 | }
75 | if (holder instanceof BaseViewHolder)
76 | {
77 | final BaseViewHolder viewHolder = (BaseViewHolder) holder;
78 | if (null != mOnItemClickListener)
79 | {
80 | viewHolder.itemView.setOnClickListener(new View.OnClickListener()
81 | {
82 | @Override
83 | public void onClick(View v)
84 | {
85 | mOnItemClickListener.onItemClick(viewHolder.itemView, position);
86 | }
87 | });
88 | viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener()
89 | {
90 | @Override
91 | public boolean onLongClick(View v)
92 | {
93 | mOnItemClickListener.onItemLongClick(viewHolder.itemView, position);
94 | return true;
95 | }
96 | });
97 | }
98 | onBindBaseViewHolder(viewHolder, position);
99 | }
100 |
101 | if (position + 1 > mLastPosition && null != mOnLoadmoreListener && isOverParent())
102 | {
103 | showLoading(true);
104 | mOnLoadmoreListener.onLoadmore();
105 | mLastPosition = mData.size();
106 | }
107 | }
108 |
109 | public abstract void onBindBaseViewHolder(BaseViewHolder holder, final int position);
110 |
111 | /**
112 | * item是否撑满父视图
113 | *
114 | * @return
115 | */
116 | public boolean isOverParent()
117 | {
118 | return mParentHeight < mItemsHeight + mParentView.getHeaderHeight() ? true : false;
119 | }
120 |
121 | @Override
122 | public int getItemCount()
123 | {
124 | return mData.size();
125 | }
126 |
127 |
128 | public static class BaseViewHolder extends RecyclerView.ViewHolder
129 | {
130 | View itemView;
131 |
132 | public BaseViewHolder(View v)
133 | {
134 | super(v);
135 | itemView = v;
136 | }
137 | }
138 |
139 | /**
140 | * 当加载失败
141 | */
142 | public void onFailed()
143 | {
144 | progressBar.setVisibility(View.GONE);
145 | tv_hint.setVisibility(View.VISIBLE);
146 | tv_hint.setText("点击重试");
147 | tv_hint.setOnClickListener(new View.OnClickListener()
148 | {
149 | @Override
150 | public void onClick(View v)
151 | {
152 | if (null != mOnLoadmoreListener)
153 | {
154 | progressBar.setVisibility(View.VISIBLE);
155 | tv_hint.setVisibility(View.GONE);
156 | mOnLoadmoreListener.onLoadmore();
157 | }
158 | }
159 | });
160 | }
161 |
162 |
163 | /**
164 | * 当没有更多
165 | */
166 | public void onNothing()
167 | {
168 | progressBar.setVisibility(View.GONE);
169 | tv_hint.setVisibility(View.VISIBLE);
170 | tv_hint.setText("没有更多");
171 | tv_hint.setOnClickListener(null);
172 | }
173 |
174 | /**
175 | * 显示加载视图
176 | *
177 | * @param show
178 | */
179 | private void showLoading(boolean show)
180 | {
181 | if (show)
182 | {
183 | progressBar.setVisibility(View.VISIBLE);
184 | } else
185 | {
186 | progressBar.setVisibility(View.GONE);
187 | }
188 | }
189 |
190 | /**
191 | * 当数据改变时调用,替换notifyDataSetChanged()
192 | */
193 | public void notifyDataChanged()
194 | {
195 | notifyDataSetChanged();
196 | mParentView.requestLayout();
197 | }
198 |
199 | /**
200 | * 设置Item监听器
201 | *
202 | * @param onItemClickListener
203 | */
204 | public void setOnItemClickListener(OnItemClickListener onItemClickListener)
205 | {
206 | mOnItemClickListener = onItemClickListener;
207 | }
208 |
209 | /**
210 | * Item点击监听
211 | */
212 | public interface OnItemClickListener
213 | {
214 | void onItemClick(View view, int position);
215 |
216 | void onItemLongClick(View view, int position);
217 | }
218 |
219 | /**
220 | * 设置加载更多监听
221 | *
222 | * @param listener
223 | */
224 | public void setOnLoadmoreListener(OnLoadmoreListener listener)
225 | {
226 | mOnLoadmoreListener = listener;
227 | }
228 |
229 | /**
230 | * 加载更多监听
231 | */
232 | public interface OnLoadmoreListener
233 | {
234 | void onLoadmore();
235 | }
236 |
237 |
238 | }
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.AdapterView;
8 | import android.widget.AdapterView.OnItemClickListener;
9 | import android.widget.AdapterView.OnItemLongClickListener;
10 | import android.widget.ListView;
11 | import android.widget.Toast;
12 |
13 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
14 | import com.jingchen.pulltorefresh.PullToRefreshLayout.OnPullProcessListener;
15 | import com.lynnchurch.pulltorefresh.activity.PullableExpandableListViewActivity;
16 | import com.lynnchurch.pulltorefresh.activity.PullableGifActivity;
17 | import com.lynnchurch.pulltorefresh.activity.PullableGridViewActivity;
18 | import com.lynnchurch.pulltorefresh.activity.PullableImageViewActivity;
19 | import com.lynnchurch.pulltorefresh.activity.PullableListViewActivity;
20 | import com.lynnchurch.pulltorefresh.activity.PullableRecyclerViewActivity;
21 | import com.lynnchurch.pulltorefresh.activity.PullableScrollViewActivity;
22 | import com.lynnchurch.pulltorefresh.activity.PullableTextViewActivity;
23 | import com.lynnchurch.pulltorefresh.activity.PullableWebViewActivity;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * 更多详解见博客http://blog.csdn.net/zhongkejingwang/article/details/38868463
30 | *
31 | * @author 陈靖
32 | */
33 | public class MainActivity extends Activity
34 | {
35 | private ListView listView;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState)
39 | {
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.activity_main);
42 | PullToRefreshLayout pullToRefreshLayout = ((PullToRefreshLayout) findViewById(R.id.refresh_view));
43 | pullToRefreshLayout.setOnPullListener(new MyPullListener());
44 | pullToRefreshLayout.setOnRefreshProcessListener(new MyOnPullProcessListener());
45 | listView = (ListView) pullToRefreshLayout.getPullableView();
46 | initListView();
47 | }
48 |
49 | /**
50 | * ListView初始化方法
51 | */
52 | private void initListView()
53 | {
54 | List items = new ArrayList<>();
55 | items.add(getString(R.string.listview));
56 | items.add(getString(R.string.recyclerview));
57 | items.add(getString(R.string.gif_listview));
58 | items.add(getString(R.string.grid_view));
59 | items.add(getString(R.string.expandable_listview));
60 | items.add(getString(R.string.scrollview));
61 | items.add(getString(R.string.webview));
62 | items.add(getString(R.string.imageview));
63 | items.add(getString(R.string.textview));
64 | MyAdapter adapter = new MyAdapter(this, items);
65 | listView.setAdapter(adapter);
66 | listView.setOnItemLongClickListener(new OnItemLongClickListener()
67 | {
68 |
69 | @Override
70 | public boolean onItemLongClick(AdapterView> parent, View view,
71 | int position, long id)
72 | {
73 | Toast.makeText(
74 | MainActivity.this,
75 | " LongClick on "
76 | + parent.getAdapter().getItemId(position),
77 | Toast.LENGTH_SHORT).show();
78 | return true;
79 | }
80 | });
81 | listView.setOnItemClickListener(new OnItemClickListener()
82 | {
83 |
84 | @Override
85 | public void onItemClick(AdapterView> parent, View view,
86 | int position, long id)
87 | {
88 |
89 | Intent intent = new Intent();
90 | switch (position)
91 | {
92 | case 0:
93 | intent.setClass(MainActivity.this,
94 | PullableListViewActivity.class);
95 | break;
96 | case 1:
97 | intent.setClass(MainActivity.this,
98 | PullableRecyclerViewActivity.class);
99 | break;
100 | case 2:
101 | intent.setClass(MainActivity.this,
102 | PullableGifActivity.class);
103 | break;
104 | case 3:
105 | intent.setClass(MainActivity.this,
106 | PullableGridViewActivity.class);
107 | break;
108 | case 4:
109 | intent.setClass(MainActivity.this,
110 | PullableExpandableListViewActivity.class);
111 | break;
112 | case 5:
113 | intent.setClass(MainActivity.this,
114 | PullableScrollViewActivity.class);
115 | break;
116 | case 6:
117 | intent.setClass(MainActivity.this,
118 | PullableWebViewActivity.class);
119 | break;
120 | case 7:
121 | intent.setClass(MainActivity.this,
122 | PullableImageViewActivity.class);
123 | break;
124 | case 8:
125 | intent.setClass(MainActivity.this,
126 | PullableTextViewActivity.class);
127 | break;
128 |
129 | default:
130 | break;
131 | }
132 | startActivity(intent);
133 | }
134 | });
135 | }
136 |
137 |
138 | public class MyOnPullProcessListener implements OnPullProcessListener
139 | {
140 |
141 | @Override
142 | public void onPrepare(View v, int which)
143 | {
144 | // TODO Auto-generated method stub
145 |
146 | }
147 |
148 | @Override
149 | public void onStart(View v, int which)
150 | {
151 | // TODO Auto-generated method stub
152 |
153 | }
154 |
155 | @Override
156 | public void onHandling(View v, int which)
157 | {
158 | // TODO Auto-generated method stub
159 |
160 | }
161 |
162 | @Override
163 | public void onFinish(View v, int which)
164 | {
165 | // TODO Auto-generated method stub
166 |
167 | }
168 |
169 | @Override
170 | public void onPull(View v, float pullDistance, int which)
171 | {
172 | // TODO Auto-generated method stub
173 | }
174 |
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/MyAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh;
2 |
3 | import java.util.List;
4 |
5 | import android.content.Context;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.TextView;
11 |
12 | public class MyAdapter extends BaseAdapter {
13 | List items;
14 | Context context;
15 |
16 | public MyAdapter(Context context, List items) {
17 | this.context = context;
18 | this.items = items;
19 | }
20 |
21 | @Override
22 | public int getCount() {
23 | return items.size();
24 | }
25 |
26 | @Override
27 | public Object getItem(int position) {
28 | return items.get(position);
29 | }
30 |
31 | @Override
32 | public long getItemId(int position) {
33 | return position;
34 | }
35 |
36 | @Override
37 | public View getView(int position, View convertView, ViewGroup parent) {
38 | View view = LayoutInflater.from(context).inflate(R.layout.list_item_layout, null);
39 | TextView tv = (TextView) view.findViewById(R.id.tv);
40 | tv.setText(items.get(position));
41 | return view;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/MyPullListener.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
7 | import com.jingchen.pulltorefresh.PullToRefreshLayout.OnPullListener;
8 |
9 | public class MyPullListener implements OnPullListener {
10 |
11 | @Override
12 | public void onRefresh(final PullToRefreshLayout pullToRefreshLayout) {
13 | // 下拉刷新操作
14 | new Handler() {
15 | @Override
16 | public void handleMessage(Message msg) {
17 | // 千万别忘了告诉控件刷新完毕了哦!
18 | pullToRefreshLayout.refreshFinish(PullToRefreshLayout.SUCCEED);
19 | }
20 | }.sendEmptyMessageDelayed(0, 3000);
21 | }
22 |
23 | @Override
24 | public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout) {
25 | // 加载操作
26 | new Handler() {
27 | @Override
28 | public void handleMessage(Message msg) {
29 | // 千万别忘了告诉控件加载完毕了哦!
30 | pullToRefreshLayout.loadmoreFinish(PullToRefreshLayout.SUCCEED);
31 | }
32 | }.sendEmptyMessageDelayed(0, 3000);
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/MyRecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 |
10 | import com.jingchen.pulltorefresh.WrapRecyclerView;
11 |
12 | import java.util.ArrayList;
13 |
14 | public class MyRecyclerAdapter extends BaseAutoLoadMoreAdapter
15 | {
16 |
17 |
18 | public MyRecyclerAdapter(Context context, WrapRecyclerView recyclerView, ArrayList data)
19 | {
20 | super(context, recyclerView, data);
21 | }
22 |
23 | @Override
24 | public BaseViewHolder onCreateBaseViewHolder(ViewGroup parent, int viewType)
25 | {
26 | return new MyBaseViewHolder(LayoutInflater.from(
27 | mContext).inflate(R.layout.recyclerview_list_item, parent,
28 | false));
29 |
30 | }
31 |
32 | @Override
33 | public int getItemHeight(RecyclerView.ViewHolder holder)
34 | {
35 | holder.itemView.measure(0, 0);
36 | return holder.itemView.getMeasuredHeight();
37 | }
38 |
39 | @Override
40 | public void onBindBaseViewHolder(BaseViewHolder holder, int position)
41 | {
42 | MyBaseViewHolder myHolder = (MyBaseViewHolder) holder;
43 | myHolder.tv_name.setText(mData.get(position));
44 | }
45 |
46 | class MyBaseViewHolder extends BaseViewHolder
47 | {
48 | TextView tv_name;
49 |
50 | public MyBaseViewHolder(View v)
51 | {
52 | super(v);
53 | tv_name = (TextView) v.findViewById(R.id.tv_name);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableExpandableListViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.AdapterView;
10 | import android.widget.AdapterView.OnItemLongClickListener;
11 | import android.widget.BaseExpandableListAdapter;
12 | import android.widget.ExpandableListView;
13 | import android.widget.ExpandableListView.OnChildClickListener;
14 | import android.widget.ExpandableListView.OnGroupClickListener;
15 | import android.widget.TextView;
16 | import android.widget.Toast;
17 |
18 | import com.lynnchurch.pulltorefresh.MyPullListener;
19 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
20 | import com.lynnchurch.pulltorefresh.R;
21 |
22 | public class PullableExpandableListViewActivity extends Activity
23 | {
24 | ExpandableListView expandableListView;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState)
28 | {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_expandablelistview);
31 | PullToRefreshLayout ptr=(PullToRefreshLayout) findViewById(R.id.refresh_view);
32 | ptr.setOnPullListener(new MyPullListener());
33 | expandableListView=(ExpandableListView)ptr.getPullableView();
34 | initExpandableListView();
35 | }
36 |
37 | /**
38 | * ExpandableListView初始化方法
39 | */
40 | private void initExpandableListView()
41 | {
42 | expandableListView.setAdapter(new ExpandableListAdapter(this));
43 | expandableListView.setOnChildClickListener(new OnChildClickListener()
44 | {
45 |
46 | @Override
47 | public boolean onChildClick(ExpandableListView parent, View v,
48 | int groupPosition, int childPosition, long id)
49 | {
50 | Toast.makeText(
51 | PullableExpandableListViewActivity.this,
52 | " Click on group " + groupPosition + " item "
53 | + childPosition, Toast.LENGTH_SHORT).show();
54 | return true;
55 | }
56 | });
57 | expandableListView
58 | .setOnItemLongClickListener(new OnItemLongClickListener()
59 | {
60 |
61 | @Override
62 | public boolean onItemLongClick(AdapterView> parent,
63 | View view, int position, long id)
64 | {
65 | Toast.makeText(
66 | PullableExpandableListViewActivity.this,
67 | "LongClick on "
68 | + parent.getAdapter().getItemId(
69 | position), Toast.LENGTH_SHORT)
70 | .show();
71 | return true;
72 | }
73 | });
74 | expandableListView.setOnGroupClickListener(new OnGroupClickListener()
75 | {
76 |
77 | @Override
78 | public boolean onGroupClick(ExpandableListView parent, View v,
79 | int groupPosition, long id)
80 | {
81 | if (parent.isGroupExpanded(groupPosition))
82 | {
83 | // 如果展开则关闭
84 | parent.collapseGroup(groupPosition);
85 | } else
86 | {
87 | // 如果关闭则打开,注意这里是手动打开不要默认滚动否则会有bug
88 | parent.expandGroup(groupPosition);
89 | }
90 | return true;
91 | }
92 | });
93 | }
94 |
95 | class ExpandableListAdapter extends BaseExpandableListAdapter
96 | {
97 | private String[] groupsStrings;// = new String[] { "这里是group 0",
98 | // "这里是group 1", "这里是group 2" };
99 | private String[][] groupItems;
100 | private Context context;
101 |
102 | public ExpandableListAdapter(Context context)
103 | {
104 | this.context = context;
105 | groupsStrings = new String[8];
106 | for (int i = 0; i < groupsStrings.length; i++)
107 | {
108 | groupsStrings[i] = new String("这里是group " + i);
109 | }
110 | groupItems = new String[8][8];
111 | for (int i = 0; i < groupItems.length; i++)
112 | for (int j = 0; j < groupItems[i].length; j++)
113 | {
114 | groupItems[i][j] = new String("这里是group " + i + "里的item "
115 | + j);
116 | }
117 | }
118 |
119 | @Override
120 | public int getGroupCount()
121 | {
122 | return groupsStrings.length;
123 | }
124 |
125 | @Override
126 | public int getChildrenCount(int groupPosition)
127 | {
128 | return groupItems[groupPosition].length;
129 | }
130 |
131 | @Override
132 | public Object getGroup(int groupPosition)
133 | {
134 | return groupsStrings[groupPosition];
135 | }
136 |
137 | @Override
138 | public Object getChild(int groupPosition, int childPosition)
139 | {
140 | return groupItems[groupPosition][childPosition];
141 | }
142 |
143 | @Override
144 | public long getGroupId(int groupPosition)
145 | {
146 | return groupPosition;
147 | }
148 |
149 | @Override
150 | public long getChildId(int groupPosition, int childPosition)
151 | {
152 | return childPosition;
153 | }
154 |
155 | @Override
156 | public boolean hasStableIds()
157 | {
158 | return true;
159 | }
160 |
161 | @Override
162 | public View getGroupView(int groupPosition, boolean isExpanded,
163 | View convertView, ViewGroup parent)
164 | {
165 | View view = LayoutInflater.from(context).inflate(
166 | R.layout.list_item_layout, null);
167 | TextView tv = (TextView) view.findViewById(R.id.tv);
168 | tv.setText(groupsStrings[groupPosition]);
169 | return view;
170 | }
171 |
172 | @Override
173 | public View getChildView(int groupPosition, int childPosition,
174 | boolean isLastChild, View convertView, ViewGroup parent)
175 | {
176 | View view = LayoutInflater.from(context).inflate(
177 | R.layout.list_item_layout, null);
178 | TextView tv = (TextView) view.findViewById(R.id.tv);
179 | tv.setText(groupItems[groupPosition][childPosition]);
180 | return view;
181 | }
182 |
183 | @Override
184 | public boolean isChildSelectable(int groupPosition, int childPosition)
185 | {
186 | return true;
187 | }
188 |
189 | }
190 |
191 | }
192 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableGifActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import java.io.IOException;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import pl.droidsonroids.gif.GifDrawable;
8 | import com.lynnchurch.pulltorefresh.MyAdapter;
9 | import com.lynnchurch.pulltorefresh.MyPullListener;
10 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
11 | import com.lynnchurch.pulltorefresh.R;
12 |
13 | import android.app.Activity;
14 | import android.content.res.Resources.NotFoundException;
15 | import android.os.Bundle;
16 | import android.view.View;
17 | import android.widget.AdapterView;
18 | import android.widget.ListView;
19 | import android.widget.Toast;
20 | import android.widget.AdapterView.OnItemClickListener;
21 | import android.widget.AdapterView.OnItemLongClickListener;
22 |
23 | public class PullableGifActivity extends Activity
24 | {
25 |
26 | private ListView listView;
27 | private PullToRefreshLayout ptrl;
28 | private boolean isFirstIn=true;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState)
32 | {
33 | super.onCreate(savedInstanceState);
34 | setContentView(R.layout.activity_listview);
35 | ptrl = ((PullToRefreshLayout) findViewById(R.id.refresh_view));
36 | ptrl.setOnPullListener(new MyPullListener());
37 | // 设置带gif动画的上拉头与下拉头
38 | try
39 | {
40 | ptrl.setGifRefreshView(new GifDrawable(getResources(), R.drawable.anim));
41 | ptrl.setGifLoadmoreView(new GifDrawable(getResources(), R.drawable.anim));
42 |
43 | } catch (NotFoundException e)
44 | {
45 | // TODO Auto-generated catch block
46 | e.printStackTrace();
47 | } catch (IOException e)
48 | {
49 | // TODO Auto-generated catch block
50 | e.printStackTrace();
51 | }
52 | listView = (ListView) ptrl.getPullableView();
53 | initListView();
54 | }
55 |
56 | @Override
57 | public void onWindowFocusChanged(boolean hasFocus)
58 | {
59 | super.onWindowFocusChanged(hasFocus);
60 | // 第一次进入自动刷新
61 | if (isFirstIn)
62 | {
63 | ptrl.autoRefresh();
64 | isFirstIn = false;
65 | }
66 | }
67 |
68 | /**
69 | * ListView初始化方法
70 | */
71 | private void initListView()
72 | {
73 | List items = new ArrayList();
74 | for (int i = 0; i < 30; i++)
75 | {
76 | items.add("这里是item " + i);
77 | }
78 | MyAdapter adapter = new MyAdapter(this, items);
79 | listView.setAdapter(adapter);
80 | listView.setOnItemLongClickListener(new OnItemLongClickListener()
81 | {
82 |
83 | @Override
84 | public boolean onItemLongClick(AdapterView> parent, View view,
85 | int position, long id)
86 | {
87 | Toast.makeText(
88 | PullableGifActivity.this,
89 | "LongClick on "
90 | + parent.getAdapter().getItemId(position),
91 | Toast.LENGTH_SHORT).show();
92 | return true;
93 | }
94 | });
95 | listView.setOnItemClickListener(new OnItemClickListener()
96 | {
97 |
98 | @Override
99 | public void onItemClick(AdapterView> parent, View view,
100 | int position, long id)
101 | {
102 | Toast.makeText(PullableGifActivity.this,
103 | " Click on " + parent.getAdapter().getItemId(position),
104 | Toast.LENGTH_SHORT).show();
105 | }
106 | });
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableGridViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.app.Activity;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.AdapterView;
10 | import android.widget.AdapterView.OnItemClickListener;
11 | import android.widget.AdapterView.OnItemLongClickListener;
12 | import android.widget.GridView;
13 | import android.widget.Toast;
14 |
15 | import com.lynnchurch.pulltorefresh.MyAdapter;
16 | import com.lynnchurch.pulltorefresh.MyPullListener;
17 | import com.lynnchurch.pulltorefresh.R;
18 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
19 |
20 | public class PullableGridViewActivity extends Activity {
21 | GridView gridView;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_gridview);
27 | PullToRefreshLayout ptr = (PullToRefreshLayout) findViewById(R.id.refresh_view);
28 | ptr.setOnPullListener(new MyPullListener());
29 | gridView = (GridView) ptr.getPullableView();
30 | initGridView();
31 | }
32 |
33 | /**
34 | * GridView初始化方法
35 | */
36 | private void initGridView() {
37 | List items = new ArrayList();
38 | for (int i = 0; i < 30; i++) {
39 | items.add("这里是item " + i);
40 | }
41 | MyAdapter adapter = new MyAdapter(this, items);
42 | gridView.setAdapter(adapter);
43 | gridView.setOnItemLongClickListener(new OnItemLongClickListener() {
44 |
45 | @Override
46 | public boolean onItemLongClick(AdapterView> parent, View view,
47 | int position, long id) {
48 | Toast.makeText(
49 | PullableGridViewActivity.this,
50 | "LongClick on "
51 | + parent.getAdapter().getItemId(position),
52 | Toast.LENGTH_SHORT).show();
53 | return true;
54 | }
55 | });
56 | gridView.setOnItemClickListener(new OnItemClickListener() {
57 |
58 | @Override
59 | public void onItemClick(AdapterView> parent, View view,
60 | int position, long id) {
61 | Toast.makeText(PullableGridViewActivity.this,
62 | " Click on " + parent.getAdapter().getItemId(position),
63 | Toast.LENGTH_SHORT).show();
64 | }
65 | });
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableImageViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import com.lynnchurch.pulltorefresh.MyPullListener;
4 | import com.lynnchurch.pulltorefresh.R;
5 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
6 |
7 | import android.app.Activity;
8 | import android.os.Bundle;
9 |
10 | public class PullableImageViewActivity extends Activity {
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_imageview);
15 | PullToRefreshLayout ptr = (PullToRefreshLayout) findViewById(R.id.refresh_view);
16 | ptr.setOnPullListener(new MyPullListener());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableListViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.app.Activity;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.AdapterView;
10 | import android.widget.AdapterView.OnItemClickListener;
11 | import android.widget.AdapterView.OnItemLongClickListener;
12 | import android.widget.ListView;
13 | import android.widget.Toast;
14 |
15 | import com.lynnchurch.pulltorefresh.MyAdapter;
16 | import com.lynnchurch.pulltorefresh.MyPullListener;
17 | import com.lynnchurch.pulltorefresh.R;
18 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
19 |
20 | public class PullableListViewActivity extends Activity
21 | {
22 | private ListView listView;
23 | private PullToRefreshLayout ptrl;
24 | private boolean isFirstIn = true;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState)
28 | {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_listview);
31 | ptrl = ((PullToRefreshLayout) findViewById(R.id.refresh_view));
32 | ptrl.setOnPullListener(new MyPullListener());
33 | listView = (ListView) ptrl.getPullableView();
34 | initListView();
35 | }
36 |
37 | @Override
38 | public void onWindowFocusChanged(boolean hasFocus)
39 | {
40 | super.onWindowFocusChanged(hasFocus);
41 | // 第一次进入自动刷新
42 | if (isFirstIn)
43 | {
44 | ptrl.autoRefresh();
45 | isFirstIn = false;
46 | }
47 | }
48 |
49 | /**
50 | * ListView初始化方法
51 | */
52 | private void initListView()
53 | {
54 | List items = new ArrayList();
55 | for (int i = 0; i < 30; i++)
56 | {
57 | items.add("这里是item " + i);
58 | }
59 | MyAdapter adapter = new MyAdapter(this, items);
60 | listView.setAdapter(adapter);
61 | listView.setOnItemLongClickListener(new OnItemLongClickListener()
62 | {
63 |
64 | @Override
65 | public boolean onItemLongClick(AdapterView> parent, View view,
66 | int position, long id)
67 | {
68 | Toast.makeText(
69 | PullableListViewActivity.this,
70 | "LongClick on "
71 | + parent.getAdapter().getItemId(position),
72 | Toast.LENGTH_SHORT).show();
73 | return true;
74 | }
75 | });
76 | listView.setOnItemClickListener(new OnItemClickListener()
77 | {
78 |
79 | @Override
80 | public void onItemClick(AdapterView> parent, View view,
81 | int position, long id)
82 | {
83 | Toast.makeText(PullableListViewActivity.this,
84 | " Click on " + parent.getAdapter().getItemId(position),
85 | Toast.LENGTH_SHORT).show();
86 | }
87 | });
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableRecyclerViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Message;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.util.Log;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.widget.Toast;
12 |
13 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
14 | import com.jingchen.pulltorefresh.WrapRecyclerView;
15 | import com.lynnchurch.pulltorefresh.MyPullListener;
16 | import com.lynnchurch.pulltorefresh.MyRecyclerAdapter;
17 | import com.lynnchurch.pulltorefresh.R;
18 |
19 | import java.util.ArrayList;
20 |
21 | public class PullableRecyclerViewActivity extends Activity
22 | {
23 | private static final String TAG = PullableRecyclerViewActivity.class.getSimpleName();
24 | private WrapRecyclerView recycler_view;
25 | private PullToRefreshLayout ptrl;
26 | private ArrayList mData = new ArrayList<>();
27 | private MyRecyclerAdapter mAdapter;
28 | private int mRequestCount; // 请求次数
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState)
32 | {
33 | super.onCreate(savedInstanceState);
34 | setContentView(R.layout.activity_recyclerview);
35 | ptrl = ((PullToRefreshLayout) findViewById(R.id.refresh_view));
36 | ptrl.setPullUpEnable(false);
37 | ptrl.setOnPullListener(new MyPullListener());
38 | recycler_view = (WrapRecyclerView) ptrl.getPullableView();
39 |
40 | View headerView = LayoutInflater.from(this).inflate(R.layout.header, null);
41 | recycler_view.addHeaderView(headerView);
42 | initRecyclerView();
43 | }
44 |
45 | /**
46 | * ListView初始化方法
47 | */
48 | private void initRecyclerView()
49 | {
50 | for (int i = 0; i < 10; i++)
51 | {
52 | mData.add("这里是item " + i);
53 | }
54 | // 设置列表
55 | recycler_view.setLayoutManager(new LinearLayoutManager(this));
56 | mAdapter = new MyRecyclerAdapter(this, recycler_view, mData);
57 | mAdapter.setOnLoadmoreListener(new MyRecyclerAdapter.OnLoadmoreListener()
58 | {
59 | @Override
60 | public void onLoadmore()
61 | {
62 | mRequestCount++;
63 | new Handler()
64 | {
65 | @Override
66 | public void handleMessage(Message msg)
67 | {
68 | if (3 == mRequestCount)
69 | {
70 | // 请求失败时
71 | mAdapter.onFailed();
72 | return;
73 | }
74 | if (5 == mRequestCount)
75 | {
76 | // 没有更多内容时
77 | mAdapter.onNothing();
78 | return;
79 | }
80 | int size = mData.size();
81 | for (int i = size; i < size + 5; i++)
82 | {
83 | mData.add("这里是item " + i);
84 | }
85 | mAdapter.notifyDataChanged();
86 | Log.i(TAG, "加载更多成功");
87 | }
88 | }.sendEmptyMessageDelayed(0, 3000);
89 | }
90 | });
91 | mAdapter.setOnItemClickListener(new MyRecyclerAdapter.OnItemClickListener()
92 | {
93 | @Override
94 | public void onItemClick(View view, int position)
95 | {
96 | Toast.makeText(PullableRecyclerViewActivity.this,
97 | " Click on " + mData.get(position),
98 | Toast.LENGTH_SHORT).show();
99 | }
100 |
101 | @Override
102 | public void onItemLongClick(View view, int position)
103 | {
104 | Toast.makeText(
105 | PullableRecyclerViewActivity.this,
106 | "LongClick on "
107 | + mData.get(position),
108 | Toast.LENGTH_SHORT).show();
109 | }
110 | });
111 | recycler_view.setAdapter(mAdapter);
112 | }
113 |
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableScrollViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import com.lynnchurch.pulltorefresh.MyPullListener;
4 | import com.lynnchurch.pulltorefresh.R;
5 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
6 |
7 | import android.app.Activity;
8 | import android.os.Bundle;
9 |
10 | public class PullableScrollViewActivity extends Activity
11 | {
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState)
14 | {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_scrollview);
17 | ((PullToRefreshLayout) findViewById(R.id.refresh_view))
18 | .setOnPullListener(new MyPullListener());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableTextViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import com.lynnchurch.pulltorefresh.MyPullListener;
4 | import com.lynnchurch.pulltorefresh.R;
5 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
6 |
7 | import android.app.Activity;
8 | import android.os.Bundle;
9 |
10 | public class PullableTextViewActivity extends Activity
11 | {
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState)
14 | {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_textview);
17 | ((PullToRefreshLayout) findViewById(R.id.refresh_view))
18 | .setOnPullListener(new MyPullListener());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/java/com/lynnchurch/pulltorefresh/activity/PullableWebViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lynnchurch.pulltorefresh.activity;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.webkit.WebView;
6 |
7 | import com.lynnchurch.pulltorefresh.MyPullListener;
8 | import com.lynnchurch.pulltorefresh.R;
9 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
10 |
11 | public class PullableWebViewActivity extends Activity
12 | {
13 | WebView webView;
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState)
17 | {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_webview);
20 | ((PullToRefreshLayout) findViewById(R.id.refresh_view))
21 | .setOnPullListener(new MyPullListener());
22 | webView = (WebView) findViewById(R.id.content_view);
23 | webView.loadUrl("http://blog.csdn.net/zhongkejingwang");
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/main1.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/anim.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/anim.gif
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/h.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/h.jpg
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/i.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/i.jpg
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/j.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/j.jpg
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/k.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/k.jpg
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/l.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/l.jpg
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/load_failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/load_failed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/load_succeed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/load_succeed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/loading.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/m.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/m.jpg
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/pull_icon_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/pull_icon_big.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/pullup_icon_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/pullup_icon_big.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/refresh_failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/refresh_failed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/refresh_succeed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/refresh_succeed.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/refreshing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xhdpi/refreshing.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/PullToRefresh/pullToRefreshsample/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_expandablelistview.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_gridview.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
17 |
18 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_imageview.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_listview.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_recyclerview.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_scrollview.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
11 |
14 |
15 |
21 |
22 |
26 |
27 |
31 |
32 |
36 |
40 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_textview.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
16 |
17 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/activity_webview.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/header.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/list_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/loadmore.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
25 |
26 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/layout/recyclerview_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
20 |
21 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #000000
5 | #aaaaaa
6 | #6593cb
7 |
8 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 通用版下拉刷新上拉加载控件
5 | 这里是HeadView
6 | 下拉刷新
7 | 释放立即刷新
8 | 正在刷新...
9 | 刷新成功
10 | 已是最新
11 | 上拉加载更多
12 | 释放立即加载
13 | 正在加载...
14 | 加载成功
15 | 已全部加载
16 | 可下拉刷新上拉加载的ListView
17 | 滑动到底部自动加载的RecyclerView
18 | 带Gif动画的可下拉刷新上拉加载的ListView
19 | 可下拉刷新上拉加载的GridView
20 | 可下拉刷新上拉加载的ExpandableListView
21 | 可下拉刷新上拉加载的ScrollView
22 | 可下拉刷新上拉加载的WebView
23 | 可下拉刷新上拉加载的ImageView
24 | 可下拉刷新上拉加载的TextView
25 |
26 |
--------------------------------------------------------------------------------
/PullToRefresh/pullToRefreshsample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/PullToRefresh/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':pullToRefreshlibrary'
2 | include ':pullToRefreshsample'
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DEPRECATED 建议选择https://github.com/CymChad/BaseRecyclerViewAdapterHelper
2 |
3 | # PullToRefresh
4 | 一个可下拉刷新与上拉加载更多的库(可轻松实现滑动到底部自动加载的功能),可对RecyclerView、ListView、GridView、WebView、ScrollView等几乎所有常用的View类型进行此操作,能够自动下拉刷新,并且还提供了GIF动画的上拉与下拉头,也可自定义上拉头与下拉头。(本库基于https://github.com/jingchenUSTC/PullToRefreshAndLoad ,特此感谢)
5 |
6 | ##效果图
7 |
8 | 
9 |
10 | ##使用示例代码
11 |
12 | 布局文件
13 | ```xml
14 |
20 |
21 |
26 |
27 |
28 | ```
29 |
30 | 使用代码
31 | ```java
32 | package com.jingchen.pulltorefresh.activity;
33 |
34 | import java.io.IOException;
35 | import java.util.ArrayList;
36 | import java.util.List;
37 |
38 | import pl.droidsonroids.gif.GifDrawable;
39 | import com.jingchen.pulltorefresh.MyAdapter;
40 | import com.jingchen.pulltorefresh.MyPullListener;
41 | import com.jingchen.pulltorefresh.PullToRefreshLayout;
42 | import com.jingchen.pulltorefresh.R;
43 | import android.app.Activity;
44 | import android.content.res.Resources.NotFoundException;
45 | import android.os.Bundle;
46 | import android.view.View;
47 | import android.widget.AdapterView;
48 | import android.widget.ListView;
49 | import android.widget.Toast;
50 | import android.widget.AdapterView.OnItemClickListener;
51 | import android.widget.AdapterView.OnItemLongClickListener;
52 |
53 | public class PullableGifActivity extends Activity
54 | {
55 |
56 | private ListView listView;
57 | private PullToRefreshLayout ptrl;
58 | private boolean isFirstIn=true;
59 |
60 | @Override
61 | protected void onCreate(Bundle savedInstanceState)
62 | {
63 | super.onCreate(savedInstanceState);
64 | setContentView(R.layout.activity_listview);
65 | ptrl = ((PullToRefreshLayout) findViewById(R.id.refresh_view));
66 | // 此处设置下拉刷新或上拉加载更多监听器
67 | ptrl.setOnPullListener(new MyPullListener());
68 | // 设置带gif动画的上拉头与下拉头
69 | try
70 | {
71 | ptrl.setGifRefreshView(new GifDrawable(getResources(), R.drawable.anim));
72 | ptrl.setGifLoadmoreView(new GifDrawable(getResources(), R.drawable.anim));
73 |
74 | } catch (NotFoundException e)
75 | {
76 | // TODO Auto-generated catch block
77 | e.printStackTrace();
78 | } catch (IOException e)
79 | {
80 | // TODO Auto-generated catch block
81 | e.printStackTrace();
82 | }
83 | listView = (ListView) ptrl.getPullableView();
84 | initListView();
85 | }
86 |
87 | @Override
88 | public void onWindowFocusChanged(boolean hasFocus)
89 | {
90 | super.onWindowFocusChanged(hasFocus);
91 | // 第一次进入自动刷新
92 | if (isFirstIn)
93 | {
94 | ptrl.autoRefresh();
95 | isFirstIn = false;
96 | }
97 | }
98 |
99 | /**
100 | * ListView初始化方法
101 | */
102 | private void initListView()
103 | {
104 | List items = new ArrayList();
105 | for (int i = 0; i < 30; i++)
106 | {
107 | items.add("这里是item " + i);
108 | }
109 | MyAdapter adapter = new MyAdapter(this, items);
110 | listView.setAdapter(adapter);
111 | listView.setOnItemLongClickListener(new OnItemLongClickListener()
112 | {
113 |
114 | @Override
115 | public boolean onItemLongClick(AdapterView> parent, View view,
116 | int position, long id)
117 | {
118 | Toast.makeText(
119 | PullableGifActivity.this,
120 | "LongClick on "
121 | + parent.getAdapter().getItemId(position),
122 | Toast.LENGTH_SHORT).show();
123 | return true;
124 | }
125 | });
126 | listView.setOnItemClickListener(new OnItemClickListener()
127 | {
128 |
129 | @Override
130 | public void onItemClick(AdapterView> parent, View view,
131 | int position, long id)
132 | {
133 | Toast.makeText(PullableGifActivity.this,
134 | " Click on " + parent.getAdapter().getItemId(position),
135 | Toast.LENGTH_SHORT).show();
136 | }
137 | });
138 | }
139 |
140 | /**
141 | * 下拉刷新与上拉加载更多监听器
142 | */
143 | public class MyPullListener implements OnPullListener {
144 |
145 | @Override
146 | public void onRefresh(final PullToRefreshLayout pullToRefreshLayout) {
147 | // 下拉刷新操作
148 | new Handler() {
149 | @Override
150 | public void handleMessage(Message msg) {
151 | // 千万别忘了告诉控件刷新完毕了哦!
152 | pullToRefreshLayout.refreshFinish(PullToRefreshLayout.SUCCEED);
153 | }
154 | }.sendEmptyMessageDelayed(0, 5000);
155 | }
156 |
157 | @Override
158 | public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout) {
159 | // 加载更多操作
160 | new Handler() {
161 | @Override
162 | public void handleMessage(Message msg) {
163 | // 千万别忘了告诉控件加载完毕了哦!
164 | pullToRefreshLayout.loadmoreFinish(PullToRefreshLayout.SUCCEED);
165 | }
166 | }.sendEmptyMessageDelayed(0, 5000);
167 | }
168 | }
169 | }
170 | ```
171 |
--------------------------------------------------------------------------------
/images/sample_picture.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lynnchurch/PullToRefresh/0bd505d1e02c0388ef6bbc434cceb492424bfc43/images/sample_picture.gif
--------------------------------------------------------------------------------