├── .gitignore
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── mrecyclerview
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── marshon
│ │ ├── adapters
│ │ ├── AlphaInAnimationAdapter.java
│ │ ├── AnimationAdapter.java
│ │ ├── ScaleInAnimationAdapter.java
│ │ ├── SlideInBottomAnimationAdapter.java
│ │ ├── SlideInLeftAnimationAdapter.java
│ │ └── SlideInRightAnimationAdapter.java
│ │ ├── animators
│ │ ├── BaseItemAnimator.java
│ │ ├── FadeInAnimator.java
│ │ ├── FadeInDownAnimator.java
│ │ ├── FadeInLeftAnimator.java
│ │ ├── FadeInRightAnimator.java
│ │ ├── FadeInUpAnimator.java
│ │ ├── FlipInBottomXAnimator.java
│ │ ├── FlipInLeftYAnimator.java
│ │ ├── FlipInRightYAnimator.java
│ │ ├── FlipInTopXAnimator.java
│ │ ├── LandingAnimator.java
│ │ ├── OvershootInLeftAnimator.java
│ │ ├── OvershootInRightAnimator.java
│ │ ├── ScaleInAnimator.java
│ │ ├── ScaleInBottomAnimator.java
│ │ ├── ScaleInLeftAnimator.java
│ │ ├── ScaleInRightAnimator.java
│ │ ├── ScaleInTopAnimator.java
│ │ ├── SlideInDownAnimator.java
│ │ ├── SlideInLeftAnimator.java
│ │ ├── SlideInRightAnimator.java
│ │ ├── SlideInUpAnimator.java
│ │ └── holder
│ │ │ └── AnimateViewHolder.java
│ │ ├── internal
│ │ └── ViewHelper.java
│ │ ├── mrecyclerview
│ │ ├── ArrowRefreshHeader.java
│ │ ├── BaseRefreshHeader.java
│ │ ├── JellyView.java
│ │ ├── LoadingMoreFooter.java
│ │ ├── MRecyclerView.java
│ │ └── SimpleViewSwithcer.java
│ │ └── swipe
│ │ └── SwipeWraper.java
│ └── res
│ ├── drawable-hdpi
│ ├── ic_pulltorefresh_arrow.png
│ ├── loading_01.png
│ ├── loading_02.png
│ ├── loading_03.png
│ ├── loading_04.png
│ ├── loading_05.png
│ ├── loading_06.png
│ ├── loading_07.png
│ ├── loading_08.png
│ ├── loading_09.png
│ ├── loading_10.png
│ ├── loading_11.png
│ ├── loading_12.png
│ ├── progressbar.xml
│ └── ptrhead.png
│ ├── layout
│ ├── listview_footer.xml
│ ├── listview_header.xml
│ ├── pull_to_refresh_head.xml
│ └── swipe.xml
│ ├── values-zh
│ └── strings.xml
│ └── values
│ ├── attrs.xml
│ └── dimens.xml
├── proguard-project.txt
├── sample
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── demotest
│ │ └── testapp
│ │ ├── ChooseAnimatorsAdapter.java
│ │ ├── MarshonRecyclerViewActivity.java
│ │ └── adapter
│ │ └── MarshonRecyclerAdapter.java
│ └── res
│ ├── drawable
│ ├── beauty.jpg
│ ├── ic_launcher.png
│ └── meinv.png
│ ├── layout
│ ├── activity_marsreview.xml
│ └── listitem.xml
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
9 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
10 | *.iml
11 | ## Directory-based project format:
12 | .idea/
13 | # if you remove the above rule, at least ignore the following:
14 | # User-specific stuff:
15 | # .idea/workspace.xml
16 | # .idea/tasks.xml
17 | # .idea/dictionaries
18 | # Sensitive or high-churn files:
19 | # .idea/dataSources.ids
20 | # .idea/dataSources.xml
21 | # .idea/sqlDataSources.xml
22 | # .idea/dynamic.xml
23 | # .idea/uiDesigner.xml
24 | # Gradle:
25 | # .idea/gradle.xml
26 | # .idea/libraries
27 | # Mongo Explorer plugin:
28 | # .idea/mongoSettings.xml
29 | ## File-based project format:
30 | *.ipr
31 | *.iws
32 | ## Plugin-specific files:
33 | # IntelliJ
34 | /out/
35 | # mpeltonen/sbt-idea plugin
36 | .idea_modules/
37 | # JIRA plugin
38 | atlassian-ide-plugin.xml
39 | # Crashlytics plugin (for Android Studio and IntelliJ)
40 | com_crashlytics_export_strings.xml
41 | crashlytics.properties
42 | crashlytics-build.properties
43 |
44 | # Built application files
45 | *.apk
46 | *.ap_
47 | # Files for the Dalvik VM
48 | *.dex
49 | # Java class files
50 | *.class
51 | # Generated files
52 | bin/
53 | gen/
54 | # Gradle files
55 | .gradle/
56 | build/
57 | /*/build/
58 | # Local configuration file (sdk path, etc)
59 | local.properties
60 | # Proguard folder generated by Eclipse
61 | proguard/
62 | # Log Files
63 | *.log
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MRecyclerView
2 | 项目CSDN地址:
3 | http://blog.csdn.net/u014665060/article/details/51241526
4 | Android RecyclerView+item动画+下拉刷新,上拉加载更多,侧滑删除(易用,可定制)(可DIY)
5 | 特别声明:开源框架并非全部本人亲手敲出来的,本人只是站在巨人的肩膀上,整合了一下别人优秀的代码,并加修改融合,希望方便到各位盆友并Get到盆友们的支持,喜欢的star或者fork下.
6 | ###下拉刷新,上拉加载更多(可DIY):
7 | 
8 |
9 | ###支持多种动画:
10 |
11 | 
12 |
13 | ###多个ItemType(只需30行代码):
14 |
15 | 
16 |
17 |
18 | #1.介绍下MReyclerView
19 |
20 |
21 | 因为之前使用过XlistView,在其可以实现下拉刷新,上拉加载更多功能上深得喜爱,可定制型也非常强,可以自己实现成类似于京东,淘宝等下拉刷新动画效果.原理差不多,加个HeaderView和FooterView作为下拉刷新和上拉加载更多.通过改变HeaderView的height来实现滑动的效果.加上属性动画让用户体验更佳.
22 |
23 |
24 |
25 | ###=============分割线=============================================================
26 |
27 | 一不小心又B了那么多,其实MRecyclerView用法没多大难度,跟RecyclerView用法一样,哎.
28 |
29 | #2.ItemAnimator
30 |
31 | 承上启下,ItemAnimator确实让人兴奋,虽然比不上5.0以上的transition动画,但是有了这些动画, 用起来也能够挺爽的不要不要的了.不信你看↓..
32 |
33 | AnimationAdapter:
34 | 这是一个装饰了RecyclerView.Adapter的类.其主要改造的地方在这里:
35 |
36 | @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
37 | mAdapter.onBindViewHolder(holder, position);
38 |
39 | int adapterPosition = holder.getAdapterPosition();
40 | if (!isFirstOnly || adapterPosition > mLastPosition) {
41 | for (Animator anim : getAnimators(holder.itemView)) {
42 | anim.setDuration(mDuration).start();
43 | anim.setInterpolator(mInterpolator);
44 | }
45 | mLastPosition = adapterPosition;
46 | } else {
47 | ViewHelper.clear(holder.itemView);
48 | }
49 | }
50 |
51 | 由于上面可以看出,在Item展示的时候是逐个读取动画来执行,并且提供了 isFirstOnly 来配置是否只是第一次展示的时候才执行动画.通过 AnimationAdapter.setFirstOnly(true);来设置.
52 | 但是 AnimationAdapter是一个抽象类, 需要重载一个类来实现里面的getAnimators方法.详细写法可参照demo里的ChooseAnimatorsAdapter类.也可以查看Xrecyclerview包下的animators包,里面提供了很多已经写好的AnimatorAdapters类,拿来即用,懒嘛..哈哈 另外提一下, 在下拉刷新和动画并不和侧滑冲突,爽爽哒
53 |
54 | #3.侧滑菜单栏
55 | 详情键SwipeWraper,只要在listietm最外层套上他,并且当做FrameLayout来使用就可以实现侧滑菜单功能.哎
56 |
57 |
58 | View deleteView = holder.itemView.findViewById(R.id.tv_delete);
59 | final SwipeWraper swipelayout = (SwipeWraper) holder.itemView.findViewById(R.id.swipelayout);
60 | deleteView.setOnClickListener(new View.OnClickListener() {
61 | @Override
62 | public void onClick(View v) {
63 | swipelayout.close(true);
64 | datas.remove(holder.getLayoutPosition()-1);
65 | animAdapter.notifyItemRemoved(holder.getLayoutPosition());
66 | }
67 | });
68 |
69 | 可以省去很多load img方法重写.
70 | 值得开心的是:产品狗一般不让一个recyclerview里面只放一种item. 这个框架作者也考虑到了这点, 写法稍微复杂点,不过有兴趣的去看下张大神的github哈.# MRecyclerView
71 |
72 |
73 |
74 | 可以省去很多load img方法重写.
75 | 产品狗一般不让一个recyclerview里面只放一种item. 这个框架作者也考虑到了这点, 写法稍微复杂点,在此安利本人喜欢的张大神的github.里面有更详细的baseadapter用法的介绍:
76 | 链接:[https://github.com/hongyangAndroid/baseAdapter](https://github.com/hongyangAndroid/baseAdapter)
77 | 还有很多功能没提,大家细细探索哈..
78 |
79 | ##THANKS PROVIDE:
80 |
81 | ItemAnimators:
82 | [https://github.com/wasabeef/recyclerview-animators](https://github.com/wasabeef/recyclerview-animators)
83 |
84 |
85 |
86 | 如以上内容造成侵权 敬请告知删除,谢谢!
87 |
88 | 联系QQ: 371166028 邮箱:itmarshon@163.com
89 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.1'
9 | // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
10 |
11 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.3.1'
12 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | jcenter()
21 | maven { url "http://dl.bintray.com/jjhesk/maven" }
22 |
23 | }
24 | }
25 |
26 | //task clean(type: Delete) {
27 | // delete rootProject.buildDir
28 | //}
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Nov 09 15:09:07 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.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/mrecyclerview/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | *.iml
3 | .idea
--------------------------------------------------------------------------------
/mrecyclerview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | minSdkVersion 14
9 | targetSdkVersion 23
10 | }
11 |
12 | }
13 |
14 | dependencies {
15 | compile 'com.android.support:appcompat-v7:23.1.0'
16 | compile 'com.android.support:recyclerview-v7:23.1.0'
17 | // compile 'jp.wasabeef:recyclerview-animators:2.2.3'
18 |
19 | }
20 |
21 |
22 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/adapters/AlphaInAnimationAdapter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.adapters;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 |
8 | /**
9 | * Copyright (C) 2015 Wasabeef
10 | *
11 | * Licensed under the Apache License, Version 2.0 (the "License");
12 | * you may not use this file except in compliance with the License.
13 | * You may obtain a copy of the License at
14 | *
15 | * http://www.apache.org/licenses/LICENSE-2.0
16 | *
17 | * Unless required by applicable law or agreed to in writing, software
18 | * distributed under the License is distributed on an "AS IS" BASIS,
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | * See the License for the specific language governing permissions and
21 | * limitations under the License.
22 | */
23 |
24 | public class AlphaInAnimationAdapter extends AnimationAdapter {
25 |
26 | private static final float DEFAULT_ALPHA_FROM = 0f;
27 | private final float mFrom;
28 |
29 | public AlphaInAnimationAdapter(RecyclerView.Adapter adapter) {
30 | this(adapter, DEFAULT_ALPHA_FROM);
31 | }
32 |
33 | public AlphaInAnimationAdapter(RecyclerView.Adapter adapter, float from) {
34 | super(adapter);
35 | mFrom = from;
36 | }
37 |
38 | @Override protected Animator[] getAnimators(View view) {
39 | return new Animator[] { ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f),ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f),ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f) };
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/adapters/AnimationAdapter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.adapters;
2 |
3 | import android.animation.Animator;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.view.animation.Interpolator;
8 | import android.view.animation.LinearInterpolator;
9 |
10 | import com.marshon.internal.ViewHelper;
11 |
12 | /**
13 | * Copyright (C) 2015 Wasabeef
14 | *
15 | * Licensed under the Apache License, Version 2.0 (the "License");
16 | * you may not use this file except in compliance with the License.
17 | * You may obtain a copy of the License at
18 | *
19 | * http://www.apache.org/licenses/LICENSE-2.0
20 | *
21 | * Unless required by applicable law or agreed to in writing, software
22 | * distributed under the License is distributed on an "AS IS" BASIS,
23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 | * See the License for the specific language governing permissions and
25 | * limitations under the License.
26 | */
27 | public abstract class AnimationAdapter extends RecyclerView.Adapter {
28 |
29 | private RecyclerView.Adapter mAdapter;
30 | private int mDuration = 300;
31 | private Interpolator mInterpolator = new LinearInterpolator();
32 | private int mLastPosition = -1;
33 |
34 | private boolean isFirstOnly = true;
35 |
36 | public AnimationAdapter(RecyclerView.Adapter adapter) {
37 | mAdapter = adapter;
38 | }
39 |
40 | @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
41 | return mAdapter.onCreateViewHolder(parent, viewType);
42 | }
43 |
44 | @Override public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
45 | super.registerAdapterDataObserver(observer);
46 | mAdapter.registerAdapterDataObserver(observer);
47 | }
48 |
49 | @Override public void unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer) {
50 | super.unregisterAdapterDataObserver(observer);
51 | mAdapter.unregisterAdapterDataObserver(observer);
52 | }
53 |
54 | @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
55 | mAdapter.onBindViewHolder(holder, position);
56 |
57 | int adapterPosition = holder.getAdapterPosition();
58 | if (!isFirstOnly || adapterPosition > mLastPosition) {
59 | for (Animator anim : getAnimators(holder.itemView)) {
60 | anim.setDuration(mDuration).start();
61 | anim.setInterpolator(mInterpolator);
62 | }
63 | mLastPosition = adapterPosition;
64 | } else {
65 | ViewHelper.clear(holder.itemView);
66 | }
67 | }
68 |
69 | @Override public void onViewRecycled(RecyclerView.ViewHolder holder) {
70 | mAdapter.onViewRecycled(holder);
71 | super.onViewRecycled(holder);
72 | }
73 |
74 | @Override public int getItemCount() {
75 | return mAdapter.getItemCount();
76 | }
77 |
78 | public void setDuration(int duration) {
79 | mDuration = duration;
80 | }
81 |
82 | public void setInterpolator(Interpolator interpolator) {
83 | mInterpolator = interpolator;
84 | }
85 |
86 | public void setStartPosition(int start) {
87 | mLastPosition = start;
88 | }
89 |
90 | protected abstract Animator[] getAnimators(View view);
91 |
92 | public void setFirstOnly(boolean firstOnly) {
93 | isFirstOnly = firstOnly;
94 | }
95 |
96 | @Override public int getItemViewType(int position) {
97 | return mAdapter.getItemViewType(position);
98 | }
99 |
100 | public RecyclerView.Adapter getWrappedAdapter() {
101 | return mAdapter;
102 | }
103 |
104 | @Override public long getItemId(int position) {
105 | return mAdapter.getItemId(position);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/adapters/ScaleInAnimationAdapter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.adapters;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 |
8 | /**
9 | * Copyright (C) 2015 Wasabeef
10 | *
11 | * Licensed under the Apache License, Version 2.0 (the "License");
12 | * you may not use this file except in compliance with the License.
13 | * You may obtain a copy of the License at
14 | *
15 | * http://www.apache.org/licenses/LICENSE-2.0
16 | *
17 | * Unless required by applicable law or agreed to in writing, software
18 | * distributed under the License is distributed on an "AS IS" BASIS,
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | * See the License for the specific language governing permissions and
21 | * limitations under the License.
22 | */
23 |
24 | public class ScaleInAnimationAdapter extends AnimationAdapter {
25 |
26 | private static final float DEFAULT_SCALE_FROM = .5f;
27 | private final float mFrom;
28 |
29 | public ScaleInAnimationAdapter(RecyclerView.Adapter adapter) {
30 | this(adapter, DEFAULT_SCALE_FROM);
31 | }
32 |
33 | public ScaleInAnimationAdapter(RecyclerView.Adapter adapter, float from) {
34 | super(adapter);
35 | mFrom = from;
36 | }
37 |
38 | @Override protected Animator[] getAnimators(View view) {
39 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f);
40 | ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f);
41 | return new ObjectAnimator[] { scaleX, scaleY };
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/adapters/SlideInBottomAnimationAdapter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.adapters;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 |
8 | /**
9 | * Copyright (C) 2015 Wasabeef
10 | *
11 | * Licensed under the Apache License, Version 2.0 (the "License");
12 | * you may not use this file except in compliance with the License.
13 | * You may obtain a copy of the License at
14 | *
15 | * http://www.apache.org/licenses/LICENSE-2.0
16 | *
17 | * Unless required by applicable law or agreed to in writing, software
18 | * distributed under the License is distributed on an "AS IS" BASIS,
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | * See the License for the specific language governing permissions and
21 | * limitations under the License.
22 | */
23 |
24 | public class SlideInBottomAnimationAdapter extends AnimationAdapter {
25 |
26 | public SlideInBottomAnimationAdapter(RecyclerView.Adapter adapter) {
27 | super(adapter);
28 | }
29 |
30 | @Override protected Animator[] getAnimators(View view) {
31 | return new Animator[] {
32 | ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0)
33 | };
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/adapters/SlideInLeftAnimationAdapter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.adapters;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 |
8 | /**
9 | * Copyright (C) 2015 Wasabeef
10 | *
11 | * Licensed under the Apache License, Version 2.0 (the "License");
12 | * you may not use this file except in compliance with the License.
13 | * You may obtain a copy of the License at
14 | *
15 | * http://www.apache.org/licenses/LICENSE-2.0
16 | *
17 | * Unless required by applicable law or agreed to in writing, software
18 | * distributed under the License is distributed on an "AS IS" BASIS,
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | * See the License for the specific language governing permissions and
21 | * limitations under the License.
22 | */
23 |
24 | public class SlideInLeftAnimationAdapter extends AnimationAdapter {
25 |
26 | public SlideInLeftAnimationAdapter(RecyclerView.Adapter adapter) {
27 | super(adapter);
28 | }
29 |
30 | @Override protected Animator[] getAnimators(View view) {
31 | return new Animator[] {
32 | ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0)
33 | };
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/adapters/SlideInRightAnimationAdapter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.adapters;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 |
8 | /**
9 | * Copyright (C) 2015 Wasabeef
10 | *
11 | * Licensed under the Apache License, Version 2.0 (the "License");
12 | * you may not use this file except in compliance with the License.
13 | * You may obtain a copy of the License at
14 | *
15 | * http://www.apache.org/licenses/LICENSE-2.0
16 | *
17 | * Unless required by applicable law or agreed to in writing, software
18 | * distributed under the License is distributed on an "AS IS" BASIS,
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 | * See the License for the specific language governing permissions and
21 | * limitations under the License.
22 | */
23 |
24 | public class SlideInRightAnimationAdapter extends AnimationAdapter {
25 |
26 | public SlideInRightAnimationAdapter(RecyclerView.Adapter adapter) {
27 | super(adapter);
28 | }
29 |
30 | @Override protected Animator[] getAnimators(View view) {
31 | return new Animator[] {
32 | ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0)
33 | };
34 | }
35 |
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/BaseItemAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 | /*
3 | * Copyright (C) 2015 Wasabeef
4 | * Copyright (C) 2014 The Android Open Source Project
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | *
18 | */
19 |
20 | import android.support.v4.view.ViewCompat;
21 | import android.support.v4.view.ViewPropertyAnimatorCompat;
22 | import android.support.v4.view.ViewPropertyAnimatorListener;
23 | import android.support.v7.widget.RecyclerView;
24 | import android.support.v7.widget.RecyclerView.ViewHolder;
25 | import android.support.v7.widget.SimpleItemAnimator;
26 | import android.view.View;
27 | import android.view.animation.Interpolator;
28 | import android.view.animation.LinearInterpolator;
29 |
30 | import com.marshon.animators.holder.AnimateViewHolder;
31 | import com.marshon.internal.ViewHelper;
32 |
33 | import java.util.ArrayList;
34 | import java.util.List;
35 |
36 | public abstract class BaseItemAnimator extends SimpleItemAnimator {
37 |
38 | private static final boolean DEBUG = false;
39 |
40 | private ArrayList mPendingRemovals = new ArrayList<>();
41 | private ArrayList mPendingAdditions = new ArrayList<>();
42 | private ArrayList mPendingMoves = new ArrayList<>();
43 | private ArrayList mPendingChanges = new ArrayList<>();
44 |
45 | private ArrayList> mAdditionsList = new ArrayList<>();
46 | private ArrayList> mMovesList = new ArrayList<>();
47 | private ArrayList> mChangesList = new ArrayList<>();
48 |
49 | protected ArrayList mAddAnimations = new ArrayList<>();
50 | private ArrayList mMoveAnimations = new ArrayList<>();
51 | protected ArrayList mRemoveAnimations = new ArrayList<>();
52 | private ArrayList mChangeAnimations = new ArrayList<>();
53 |
54 | protected Interpolator mInterpolator = new LinearInterpolator();
55 |
56 | private static class MoveInfo {
57 |
58 | public ViewHolder holder;
59 | public int fromX, fromY, toX, toY;
60 |
61 | private MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
62 | this.holder = holder;
63 | this.fromX = fromX;
64 | this.fromY = fromY;
65 | this.toX = toX;
66 | this.toY = toY;
67 | }
68 | }
69 |
70 | private static class ChangeInfo {
71 |
72 | public ViewHolder oldHolder, newHolder;
73 | public int fromX, fromY, toX, toY;
74 |
75 | private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder) {
76 | this.oldHolder = oldHolder;
77 | this.newHolder = newHolder;
78 | }
79 |
80 | private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder, int fromX, int fromY, int toX,
81 | int toY) {
82 | this(oldHolder, newHolder);
83 | this.fromX = fromX;
84 | this.fromY = fromY;
85 | this.toX = toX;
86 | this.toY = toY;
87 | }
88 |
89 | @Override public String toString() {
90 | return "ChangeInfo{" +
91 | "oldHolder=" + oldHolder +
92 | ", newHolder=" + newHolder +
93 | ", fromX=" + fromX +
94 | ", fromY=" + fromY +
95 | ", toX=" + toX +
96 | ", toY=" + toY +
97 | '}';
98 | }
99 | }
100 |
101 | public BaseItemAnimator() {
102 | super();
103 | setSupportsChangeAnimations(false);
104 | }
105 |
106 | public void setInterpolator(Interpolator mInterpolator) {
107 | this.mInterpolator = mInterpolator;
108 | }
109 |
110 | @Override public void runPendingAnimations() {
111 | boolean removalsPending = !mPendingRemovals.isEmpty();
112 | boolean movesPending = !mPendingMoves.isEmpty();
113 | boolean changesPending = !mPendingChanges.isEmpty();
114 | boolean additionsPending = !mPendingAdditions.isEmpty();
115 | if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
116 | // nothing to animate
117 | return;
118 | }
119 | // First, remove stuff
120 | for (ViewHolder holder : mPendingRemovals) {
121 | doAnimateRemove(holder);
122 | }
123 | mPendingRemovals.clear();
124 | // Next, move stuff
125 | if (movesPending) {
126 | final ArrayList moves = new ArrayList();
127 | moves.addAll(mPendingMoves);
128 | mMovesList.add(moves);
129 | mPendingMoves.clear();
130 | Runnable mover = new Runnable() {
131 | @Override public void run() {
132 | for (MoveInfo moveInfo : moves) {
133 | animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY, moveInfo.toX,
134 | moveInfo.toY);
135 | }
136 | moves.clear();
137 | mMovesList.remove(moves);
138 | }
139 | };
140 | if (removalsPending) {
141 | View view = moves.get(0).holder.itemView;
142 | ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration());
143 | } else {
144 | mover.run();
145 | }
146 | }
147 | // Next, change stuff, to run in parallel with move animations
148 | if (changesPending) {
149 | final ArrayList changes = new ArrayList();
150 | changes.addAll(mPendingChanges);
151 | mChangesList.add(changes);
152 | mPendingChanges.clear();
153 | Runnable changer = new Runnable() {
154 | @Override public void run() {
155 | for (ChangeInfo change : changes) {
156 | animateChangeImpl(change);
157 | }
158 | changes.clear();
159 | mChangesList.remove(changes);
160 | }
161 | };
162 | if (removalsPending) {
163 | ViewHolder holder = changes.get(0).oldHolder;
164 | ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration());
165 | } else {
166 | changer.run();
167 | }
168 | }
169 | // Next, add stuff
170 | if (additionsPending) {
171 | final ArrayList additions = new ArrayList();
172 | additions.addAll(mPendingAdditions);
173 | mAdditionsList.add(additions);
174 | mPendingAdditions.clear();
175 | Runnable adder = new Runnable() {
176 | public void run() {
177 | for (ViewHolder holder : additions) {
178 | doAnimateAdd(holder);
179 | }
180 | additions.clear();
181 | mAdditionsList.remove(additions);
182 | }
183 | };
184 | if (removalsPending || movesPending || changesPending) {
185 | long removeDuration = removalsPending ? getRemoveDuration() : 0;
186 | long moveDuration = movesPending ? getMoveDuration() : 0;
187 | long changeDuration = changesPending ? getChangeDuration() : 0;
188 | long totalDelay = removeDuration + Math.max(moveDuration, changeDuration);
189 | View view = additions.get(0).itemView;
190 | ViewCompat.postOnAnimationDelayed(view, adder, totalDelay);
191 | } else {
192 | adder.run();
193 | }
194 | }
195 | }
196 |
197 | protected void preAnimateRemoveImpl(final RecyclerView.ViewHolder holder) {
198 | }
199 |
200 | protected void preAnimateAddImpl(final RecyclerView.ViewHolder holder) {
201 | }
202 |
203 | protected abstract void animateRemoveImpl(final RecyclerView.ViewHolder holder);
204 |
205 | protected abstract void animateAddImpl(final RecyclerView.ViewHolder holder);
206 |
207 | private void preAnimateRemove(final RecyclerView.ViewHolder holder) {
208 | ViewHelper.clear(holder.itemView);
209 |
210 | if (holder instanceof AnimateViewHolder) {
211 | ((AnimateViewHolder) holder).preAnimateRemoveImpl();
212 | } else {
213 | preAnimateRemoveImpl(holder);
214 | }
215 | }
216 |
217 | private void preAnimateAdd(final RecyclerView.ViewHolder holder) {
218 | ViewHelper.clear(holder.itemView);
219 |
220 | if (holder instanceof AnimateViewHolder) {
221 | ((AnimateViewHolder) holder).preAnimateAddImpl();
222 | } else {
223 | preAnimateAddImpl(holder);
224 | }
225 | }
226 |
227 | private void doAnimateRemove(final RecyclerView.ViewHolder holder) {
228 | if (holder instanceof AnimateViewHolder) {
229 | ((AnimateViewHolder) holder).animateRemoveImpl(new DefaultRemoveVpaListener(holder));
230 | } else {
231 | animateRemoveImpl(holder);
232 | }
233 |
234 | mRemoveAnimations.add(holder);
235 | }
236 |
237 | private void doAnimateAdd(final RecyclerView.ViewHolder holder) {
238 | if (holder instanceof AnimateViewHolder) {
239 | ((AnimateViewHolder) holder).animateAddImpl(new DefaultAddVpaListener(holder));
240 | } else {
241 | animateAddImpl(holder);
242 | }
243 |
244 | mAddAnimations.add(holder);
245 | }
246 |
247 | @Override public boolean animateRemove(final ViewHolder holder) {
248 | endAnimation(holder);
249 | preAnimateRemove(holder);
250 | mPendingRemovals.add(holder);
251 | return true;
252 | }
253 |
254 | protected long getRemoveDelay(final RecyclerView.ViewHolder holder) {
255 | return Math.abs(holder.getOldPosition() * getRemoveDuration() / 4);
256 | }
257 |
258 | @Override public boolean animateAdd(final ViewHolder holder) {
259 | endAnimation(holder);
260 | preAnimateAdd(holder);
261 | mPendingAdditions.add(holder);
262 | return true;
263 | }
264 |
265 | protected long getAddDelay(final RecyclerView.ViewHolder holder) {
266 | return Math.abs(holder.getAdapterPosition() * getAddDuration() / 4);
267 | }
268 |
269 | @Override
270 | public boolean animateMove(final ViewHolder holder, int fromX, int fromY, int toX, int toY) {
271 | final View view = holder.itemView;
272 | fromX += ViewCompat.getTranslationX(holder.itemView);
273 | fromY += ViewCompat.getTranslationY(holder.itemView);
274 | endAnimation(holder);
275 | int deltaX = toX - fromX;
276 | int deltaY = toY - fromY;
277 | if (deltaX == 0 && deltaY == 0) {
278 | dispatchMoveFinished(holder);
279 | return false;
280 | }
281 | if (deltaX != 0) {
282 | ViewCompat.setTranslationX(view, -deltaX);
283 | }
284 | if (deltaY != 0) {
285 | ViewCompat.setTranslationY(view, -deltaY);
286 | }
287 | mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
288 | return true;
289 | }
290 |
291 | private void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) {
292 | final View view = holder.itemView;
293 | final int deltaX = toX - fromX;
294 | final int deltaY = toY - fromY;
295 | if (deltaX != 0) {
296 | ViewCompat.animate(view).translationX(0);
297 | }
298 | if (deltaY != 0) {
299 | ViewCompat.animate(view).translationY(0);
300 | }
301 | // TODO: make EndActions end listeners instead, since end actions aren't called when
302 | // vpas are canceled (and can't end them. why?)
303 | // need listener functionality in VPACompat for this. Ick.
304 | mMoveAnimations.add(holder);
305 | final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
306 | animation.setDuration(getMoveDuration()).setListener(new VpaListenerAdapter() {
307 | @Override public void onAnimationStart(View view) {
308 | dispatchMoveStarting(holder);
309 | }
310 |
311 | @Override public void onAnimationCancel(View view) {
312 | if (deltaX != 0) {
313 | ViewCompat.setTranslationX(view, 0);
314 | }
315 | if (deltaY != 0) {
316 | ViewCompat.setTranslationY(view, 0);
317 | }
318 | }
319 |
320 | @Override public void onAnimationEnd(View view) {
321 | animation.setListener(null);
322 | dispatchMoveFinished(holder);
323 | mMoveAnimations.remove(holder);
324 | dispatchFinishedWhenDone();
325 | }
326 | }).start();
327 | }
328 |
329 | @Override
330 | public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, int fromX, int fromY,
331 | int toX, int toY) {
332 | final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView);
333 | final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView);
334 | final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);
335 | endAnimation(oldHolder);
336 | int deltaX = (int) (toX - fromX - prevTranslationX);
337 | int deltaY = (int) (toY - fromY - prevTranslationY);
338 | // recover prev translation state after ending animation
339 | ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX);
340 | ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY);
341 | ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);
342 | if (newHolder != null && newHolder.itemView != null) {
343 | // carry over translation values
344 | endAnimation(newHolder);
345 | ViewCompat.setTranslationX(newHolder.itemView, -deltaX);
346 | ViewCompat.setTranslationY(newHolder.itemView, -deltaY);
347 | ViewCompat.setAlpha(newHolder.itemView, 0);
348 | }
349 | mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
350 | return true;
351 | }
352 |
353 | private void animateChangeImpl(final ChangeInfo changeInfo) {
354 | final ViewHolder holder = changeInfo.oldHolder;
355 | final View view = holder == null ? null : holder.itemView;
356 | final ViewHolder newHolder = changeInfo.newHolder;
357 | final View newView = newHolder != null ? newHolder.itemView : null;
358 | if (view != null) {
359 | mChangeAnimations.add(changeInfo.oldHolder);
360 | final ViewPropertyAnimatorCompat oldViewAnim =
361 | ViewCompat.animate(view).setDuration(getChangeDuration());
362 | oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
363 | oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
364 | oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() {
365 | @Override public void onAnimationStart(View view) {
366 | dispatchChangeStarting(changeInfo.oldHolder, true);
367 | }
368 |
369 | @Override public void onAnimationEnd(View view) {
370 | oldViewAnim.setListener(null);
371 | ViewCompat.setAlpha(view, 1);
372 | ViewCompat.setTranslationX(view, 0);
373 | ViewCompat.setTranslationY(view, 0);
374 | dispatchChangeFinished(changeInfo.oldHolder, true);
375 | mChangeAnimations.remove(changeInfo.oldHolder);
376 | dispatchFinishedWhenDone();
377 | }
378 | }).start();
379 | }
380 | if (newView != null) {
381 | mChangeAnimations.add(changeInfo.newHolder);
382 | final ViewPropertyAnimatorCompat newViewAnimation = ViewCompat.animate(newView);
383 | newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).
384 | alpha(1).setListener(new VpaListenerAdapter() {
385 | @Override public void onAnimationStart(View view) {
386 | dispatchChangeStarting(changeInfo.newHolder, false);
387 | }
388 |
389 | @Override public void onAnimationEnd(View view) {
390 | newViewAnimation.setListener(null);
391 | ViewCompat.setAlpha(newView, 1);
392 | ViewCompat.setTranslationX(newView, 0);
393 | ViewCompat.setTranslationY(newView, 0);
394 | dispatchChangeFinished(changeInfo.newHolder, false);
395 | mChangeAnimations.remove(changeInfo.newHolder);
396 | dispatchFinishedWhenDone();
397 | }
398 | }).start();
399 | }
400 | }
401 |
402 | private void endChangeAnimation(List infoList, ViewHolder item) {
403 | for (int i = infoList.size() - 1; i >= 0; i--) {
404 | ChangeInfo changeInfo = infoList.get(i);
405 | if (endChangeAnimationIfNecessary(changeInfo, item)) {
406 | if (changeInfo.oldHolder == null && changeInfo.newHolder == null) {
407 | infoList.remove(changeInfo);
408 | }
409 | }
410 | }
411 | }
412 |
413 | private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) {
414 | if (changeInfo.oldHolder != null) {
415 | endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder);
416 | }
417 | if (changeInfo.newHolder != null) {
418 | endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder);
419 | }
420 | }
421 |
422 | private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, ViewHolder item) {
423 | boolean oldItem = false;
424 | if (changeInfo.newHolder == item) {
425 | changeInfo.newHolder = null;
426 | } else if (changeInfo.oldHolder == item) {
427 | changeInfo.oldHolder = null;
428 | oldItem = true;
429 | } else {
430 | return false;
431 | }
432 | ViewCompat.setAlpha(item.itemView, 1);
433 | ViewCompat.setTranslationX(item.itemView, 0);
434 | ViewCompat.setTranslationY(item.itemView, 0);
435 | dispatchChangeFinished(item, oldItem);
436 | return true;
437 | }
438 |
439 | @Override public void endAnimation(ViewHolder item) {
440 | final View view = item.itemView;
441 | // this will trigger end callback which should set properties to their target values.
442 | ViewCompat.animate(view).cancel();
443 | // TODO if some other animations are chained to end, how do we cancel them as well?
444 | for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
445 | MoveInfo moveInfo = mPendingMoves.get(i);
446 | if (moveInfo.holder == item) {
447 | ViewCompat.setTranslationY(view, 0);
448 | ViewCompat.setTranslationX(view, 0);
449 | dispatchMoveFinished(item);
450 | mPendingMoves.remove(i);
451 | }
452 | }
453 | endChangeAnimation(mPendingChanges, item);
454 | if (mPendingRemovals.remove(item)) {
455 | ViewHelper.clear(item.itemView);
456 | dispatchRemoveFinished(item);
457 | }
458 | if (mPendingAdditions.remove(item)) {
459 | ViewHelper.clear(item.itemView);
460 | dispatchAddFinished(item);
461 | }
462 |
463 | for (int i = mChangesList.size() - 1; i >= 0; i--) {
464 | ArrayList changes = mChangesList.get(i);
465 | endChangeAnimation(changes, item);
466 | if (changes.isEmpty()) {
467 | mChangesList.remove(i);
468 | }
469 | }
470 | for (int i = mMovesList.size() - 1; i >= 0; i--) {
471 | ArrayList moves = mMovesList.get(i);
472 | for (int j = moves.size() - 1; j >= 0; j--) {
473 | MoveInfo moveInfo = moves.get(j);
474 | if (moveInfo.holder == item) {
475 | ViewCompat.setTranslationY(view, 0);
476 | ViewCompat.setTranslationX(view, 0);
477 | dispatchMoveFinished(item);
478 | moves.remove(j);
479 | if (moves.isEmpty()) {
480 | mMovesList.remove(i);
481 | }
482 | break;
483 | }
484 | }
485 | }
486 | for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
487 | ArrayList additions = mAdditionsList.get(i);
488 | if (additions.remove(item)) {
489 | ViewHelper.clear(item.itemView);
490 | dispatchAddFinished(item);
491 | if (additions.isEmpty()) {
492 | mAdditionsList.remove(i);
493 | }
494 | }
495 | }
496 |
497 | // animations should be ended by the cancel above.
498 | if (mRemoveAnimations.remove(item) && DEBUG) {
499 | throw new IllegalStateException(
500 | "after animation is cancelled, item should not be in " + "mRemoveAnimations list");
501 | }
502 |
503 | if (mAddAnimations.remove(item) && DEBUG) {
504 | throw new IllegalStateException(
505 | "after animation is cancelled, item should not be in " + "mAddAnimations list");
506 | }
507 |
508 | if (mChangeAnimations.remove(item) && DEBUG) {
509 | throw new IllegalStateException(
510 | "after animation is cancelled, item should not be in " + "mChangeAnimations list");
511 | }
512 |
513 | if (mMoveAnimations.remove(item) && DEBUG) {
514 | throw new IllegalStateException(
515 | "after animation is cancelled, item should not be in " + "mMoveAnimations list");
516 | }
517 | dispatchFinishedWhenDone();
518 | }
519 |
520 | @Override public boolean isRunning() {
521 | return (!mPendingAdditions.isEmpty() ||
522 | !mPendingChanges.isEmpty() ||
523 | !mPendingMoves.isEmpty() ||
524 | !mPendingRemovals.isEmpty() ||
525 | !mMoveAnimations.isEmpty() ||
526 | !mRemoveAnimations.isEmpty() ||
527 | !mAddAnimations.isEmpty() ||
528 | !mChangeAnimations.isEmpty() ||
529 | !mMovesList.isEmpty() ||
530 | !mAdditionsList.isEmpty() ||
531 | !mChangesList.isEmpty());
532 | }
533 |
534 | /**
535 | * Check the state of currently pending and running animations. If there are none
536 | * pending/running, call #dispatchAnimationsFinished() to notify any
537 | * listeners.
538 | */
539 | private void dispatchFinishedWhenDone() {
540 | if (!isRunning()) {
541 | dispatchAnimationsFinished();
542 | }
543 | }
544 |
545 | @Override public void endAnimations() {
546 | int count = mPendingMoves.size();
547 | for (int i = count - 1; i >= 0; i--) {
548 | MoveInfo item = mPendingMoves.get(i);
549 | View view = item.holder.itemView;
550 | ViewCompat.setTranslationY(view, 0);
551 | ViewCompat.setTranslationX(view, 0);
552 | dispatchMoveFinished(item.holder);
553 | mPendingMoves.remove(i);
554 | }
555 | count = mPendingRemovals.size();
556 | for (int i = count - 1; i >= 0; i--) {
557 | ViewHolder item = mPendingRemovals.get(i);
558 | dispatchRemoveFinished(item);
559 | mPendingRemovals.remove(i);
560 | }
561 | count = mPendingAdditions.size();
562 | for (int i = count - 1; i >= 0; i--) {
563 | ViewHolder item = mPendingAdditions.get(i);
564 | ViewHelper.clear(item.itemView);
565 | dispatchAddFinished(item);
566 | mPendingAdditions.remove(i);
567 | }
568 | count = mPendingChanges.size();
569 | for (int i = count - 1; i >= 0; i--) {
570 | endChangeAnimationIfNecessary(mPendingChanges.get(i));
571 | }
572 | mPendingChanges.clear();
573 | if (!isRunning()) {
574 | return;
575 | }
576 |
577 | int listCount = mMovesList.size();
578 | for (int i = listCount - 1; i >= 0; i--) {
579 | ArrayList moves = mMovesList.get(i);
580 | count = moves.size();
581 | for (int j = count - 1; j >= 0; j--) {
582 | MoveInfo moveInfo = moves.get(j);
583 | ViewHolder item = moveInfo.holder;
584 | View view = item.itemView;
585 | ViewCompat.setTranslationY(view, 0);
586 | ViewCompat.setTranslationX(view, 0);
587 | dispatchMoveFinished(moveInfo.holder);
588 | moves.remove(j);
589 | if (moves.isEmpty()) {
590 | mMovesList.remove(moves);
591 | }
592 | }
593 | }
594 | listCount = mAdditionsList.size();
595 | for (int i = listCount - 1; i >= 0; i--) {
596 | ArrayList additions = mAdditionsList.get(i);
597 | count = additions.size();
598 | for (int j = count - 1; j >= 0; j--) {
599 | ViewHolder item = additions.get(j);
600 | View view = item.itemView;
601 | ViewCompat.setAlpha(view, 1);
602 | dispatchAddFinished(item);
603 | //this check prevent exception when removal already happened during finishing animation
604 | if (j < additions.size()) {
605 | additions.remove(j);
606 | }
607 | if (additions.isEmpty()) {
608 | mAdditionsList.remove(additions);
609 | }
610 | }
611 | }
612 | listCount = mChangesList.size();
613 | for (int i = listCount - 1; i >= 0; i--) {
614 | ArrayList changes = mChangesList.get(i);
615 | count = changes.size();
616 | for (int j = count - 1; j >= 0; j--) {
617 | endChangeAnimationIfNecessary(changes.get(j));
618 | if (changes.isEmpty()) {
619 | mChangesList.remove(changes);
620 | }
621 | }
622 | }
623 |
624 | cancelAll(mRemoveAnimations);
625 | cancelAll(mMoveAnimations);
626 | cancelAll(mAddAnimations);
627 | cancelAll(mChangeAnimations);
628 |
629 | dispatchAnimationsFinished();
630 | }
631 |
632 | void cancelAll(List viewHolders) {
633 | for (int i = viewHolders.size() - 1; i >= 0; i--) {
634 | ViewCompat.animate(viewHolders.get(i).itemView).cancel();
635 | }
636 | }
637 |
638 | private static class VpaListenerAdapter implements ViewPropertyAnimatorListener {
639 |
640 | @Override public void onAnimationStart(View view) {
641 | }
642 |
643 | @Override public void onAnimationEnd(View view) {
644 | }
645 |
646 | @Override public void onAnimationCancel(View view) {
647 | }
648 | }
649 |
650 | protected class DefaultAddVpaListener extends VpaListenerAdapter {
651 |
652 | RecyclerView.ViewHolder mViewHolder;
653 |
654 | public DefaultAddVpaListener(final RecyclerView.ViewHolder holder) {
655 | mViewHolder = holder;
656 | }
657 |
658 | @Override public void onAnimationStart(View view) {
659 | dispatchAddStarting(mViewHolder);
660 | }
661 |
662 | @Override public void onAnimationCancel(View view) {
663 | ViewHelper.clear(view);
664 | }
665 |
666 | @Override public void onAnimationEnd(View view) {
667 | ViewHelper.clear(view);
668 | dispatchAddFinished(mViewHolder);
669 | mAddAnimations.remove(mViewHolder);
670 | dispatchFinishedWhenDone();
671 | }
672 | }
673 |
674 | protected class DefaultRemoveVpaListener extends VpaListenerAdapter {
675 |
676 | RecyclerView.ViewHolder mViewHolder;
677 |
678 | public DefaultRemoveVpaListener(final RecyclerView.ViewHolder holder) {
679 | mViewHolder = holder;
680 | }
681 |
682 | @Override public void onAnimationStart(View view) {
683 | dispatchRemoveStarting(mViewHolder);
684 | }
685 |
686 | @Override public void onAnimationCancel(View view) {
687 | ViewHelper.clear(view);
688 | }
689 |
690 | @Override public void onAnimationEnd(View view) {
691 | ViewHelper.clear(view);
692 | dispatchRemoveFinished(mViewHolder);
693 | mRemoveAnimations.remove(mViewHolder);
694 | dispatchFinishedWhenDone();
695 | }
696 | }
697 | }
698 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FadeInAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FadeInAnimator extends BaseItemAnimator {
24 |
25 | public FadeInAnimator() {
26 | }
27 |
28 | public FadeInAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .alpha(0)
35 | .setDuration(getRemoveDuration())
36 | .setInterpolator(mInterpolator)
37 | .setListener(new DefaultRemoveVpaListener(holder))
38 | .setStartDelay(getRemoveDelay(holder))
39 | .start();
40 | }
41 |
42 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
43 | ViewCompat.setAlpha(holder.itemView, 0);
44 | }
45 |
46 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
47 | ViewCompat.animate(holder.itemView)
48 | .alpha(1)
49 | .setDuration(getAddDuration())
50 | .setInterpolator(mInterpolator)
51 | .setListener(new DefaultAddVpaListener(holder))
52 | .setStartDelay(getAddDelay(holder))
53 | .start();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FadeInDownAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FadeInDownAnimator extends BaseItemAnimator {
24 |
25 | public FadeInDownAnimator() {
26 | }
27 |
28 | public FadeInDownAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .translationY(-holder.itemView.getHeight() * .25f)
35 | .alpha(0)
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setTranslationY(holder.itemView, -holder.itemView.getHeight() * .25f);
45 | ViewCompat.setAlpha(holder.itemView, 0);
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .translationY(0)
51 | .alpha(1)
52 | .setDuration(getAddDuration())
53 | .setInterpolator(mInterpolator)
54 | .setListener(new DefaultAddVpaListener(holder))
55 | .setStartDelay(getAddDelay(holder))
56 | .start();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FadeInLeftAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FadeInLeftAnimator extends BaseItemAnimator {
24 |
25 | public FadeInLeftAnimator() {
26 | }
27 |
28 | public FadeInLeftAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .translationX(-holder.itemView.getRootView().getWidth() * .25f)
35 | .alpha(0)
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setTranslationX(holder.itemView, -holder.itemView.getRootView().getWidth() * .25f);
45 | ViewCompat.setAlpha(holder.itemView, 0);
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .translationX(0)
51 | .alpha(1)
52 | .setDuration(getAddDuration())
53 | .setInterpolator(mInterpolator)
54 | .setListener(new DefaultAddVpaListener(holder))
55 | .setStartDelay(getAddDelay(holder))
56 | .start();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FadeInRightAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FadeInRightAnimator extends BaseItemAnimator {
24 |
25 | public FadeInRightAnimator() {
26 | }
27 |
28 | public FadeInRightAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .translationX(holder.itemView.getRootView().getWidth() * .25f)
35 | .alpha(0)
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setTranslationX(holder.itemView, holder.itemView.getRootView().getWidth() * .25f);
45 | ViewCompat.setAlpha(holder.itemView, 0);
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .translationX(0)
51 | .alpha(1)
52 | .setDuration(getAddDuration())
53 | .setInterpolator(mInterpolator)
54 | .setListener(new DefaultAddVpaListener(holder))
55 | .setStartDelay(getAddDelay(holder))
56 | .start();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FadeInUpAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FadeInUpAnimator extends BaseItemAnimator {
24 |
25 | public FadeInUpAnimator() {
26 | }
27 |
28 | public FadeInUpAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .translationY(holder.itemView.getHeight() * .25f)
35 | .alpha(0)
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setTranslationY(holder.itemView, holder.itemView.getHeight() * .25f);
45 | ViewCompat.setAlpha(holder.itemView, 0);
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .translationY(0)
51 | .alpha(1)
52 | .setDuration(getAddDuration())
53 | .setInterpolator(mInterpolator)
54 | .setListener(new DefaultAddVpaListener(holder))
55 | .setStartDelay(getAddDelay(holder))
56 | .start();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FlipInBottomXAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FlipInBottomXAnimator extends BaseItemAnimator {
24 |
25 | public FlipInBottomXAnimator() {
26 | }
27 |
28 | public FlipInBottomXAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .rotationX(-90)
35 | .setDuration(getRemoveDuration())
36 | .setInterpolator(mInterpolator)
37 | .setListener(new DefaultRemoveVpaListener(holder))
38 | .setStartDelay(getRemoveDelay(holder))
39 | .start();
40 | }
41 |
42 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
43 | ViewCompat.setRotationX(holder.itemView, -90);
44 | }
45 |
46 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
47 | ViewCompat.animate(holder.itemView)
48 | .rotationX(0)
49 | .setDuration(getAddDuration())
50 | .setInterpolator(mInterpolator)
51 | .setListener(new DefaultAddVpaListener(holder))
52 | .setStartDelay(getAddDelay(holder))
53 | .start();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FlipInLeftYAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FlipInLeftYAnimator extends BaseItemAnimator {
24 |
25 | public FlipInLeftYAnimator() {
26 | }
27 |
28 | public FlipInLeftYAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .rotationY(90)
35 | .setDuration(getRemoveDuration())
36 | .setInterpolator(mInterpolator)
37 | .setListener(new DefaultRemoveVpaListener(holder))
38 | .setStartDelay(getRemoveDelay(holder))
39 | .start();
40 | }
41 |
42 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
43 | ViewCompat.setRotationY(holder.itemView, 90);
44 | }
45 |
46 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
47 | ViewCompat.animate(holder.itemView)
48 | .rotationY(0)
49 | .setDuration(getAddDuration())
50 | .setInterpolator(mInterpolator)
51 | .setListener(new DefaultAddVpaListener(holder))
52 | .setStartDelay(getAddDelay(holder))
53 | .start();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FlipInRightYAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FlipInRightYAnimator extends BaseItemAnimator {
24 |
25 | public FlipInRightYAnimator() {
26 | }
27 |
28 | public FlipInRightYAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .rotationY(-90)
35 | .setDuration(getRemoveDuration())
36 | .setInterpolator(mInterpolator)
37 | .setListener(new DefaultRemoveVpaListener(holder))
38 | .setStartDelay(getRemoveDelay(holder))
39 | .start();
40 | }
41 |
42 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
43 | ViewCompat.setRotationY(holder.itemView, -90);
44 | }
45 |
46 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
47 | ViewCompat.animate(holder.itemView)
48 | .rotationY(0)
49 | .setDuration(getAddDuration())
50 | .setInterpolator(mInterpolator)
51 | .setListener(new DefaultAddVpaListener(holder))
52 | .setStartDelay(getAddDelay(holder))
53 | .start();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/FlipInTopXAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class FlipInTopXAnimator extends BaseItemAnimator {
24 |
25 | public FlipInTopXAnimator() {
26 | }
27 |
28 | public FlipInTopXAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .rotationX(90)
35 | .setDuration(getRemoveDuration())
36 | .setInterpolator(mInterpolator)
37 | .setListener(new DefaultRemoveVpaListener(holder))
38 | .setStartDelay(getRemoveDelay(holder))
39 | .start();
40 | }
41 |
42 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
43 | ViewCompat.setRotationX(holder.itemView, 90);
44 | }
45 |
46 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
47 | ViewCompat.animate(holder.itemView)
48 | .rotationX(0)
49 | .setDuration(getAddDuration())
50 | .setInterpolator(mInterpolator)
51 | .setListener(new DefaultAddVpaListener(holder))
52 | .setStartDelay(getAddDelay(holder))
53 | .start();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/LandingAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class LandingAnimator extends BaseItemAnimator {
24 |
25 | public LandingAnimator() {
26 | }
27 |
28 | public LandingAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .alpha(0)
35 | .scaleX(1.5f)
36 | .scaleY(1.5f)
37 | .setDuration(getRemoveDuration())
38 | .setInterpolator(mInterpolator)
39 | .setListener(new DefaultRemoveVpaListener(holder))
40 | .setStartDelay(getRemoveDelay(holder))
41 | .start();
42 | }
43 |
44 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
45 | ViewCompat.setAlpha(holder.itemView, 0);
46 | ViewCompat.setScaleX(holder.itemView, 1.5f);
47 | ViewCompat.setScaleY(holder.itemView, 1.5f);
48 | }
49 |
50 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
51 | ViewCompat.animate(holder.itemView)
52 | .alpha(1)
53 | .scaleX(1)
54 | .scaleY(1)
55 | .setDuration(getAddDuration())
56 | .setInterpolator(mInterpolator)
57 | .setListener(new DefaultAddVpaListener(holder))
58 | .setStartDelay(getAddDelay(holder))
59 | .start();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/OvershootInLeftAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.OvershootInterpolator;
22 |
23 | public class OvershootInLeftAnimator extends BaseItemAnimator {
24 |
25 | private final float mTension;
26 |
27 | public OvershootInLeftAnimator() {
28 | mTension = 2.0f;
29 | }
30 |
31 | public OvershootInLeftAnimator(float mTension) {
32 | this.mTension = mTension;
33 | }
34 |
35 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
36 | ViewCompat.animate(holder.itemView)
37 | .translationX(-holder.itemView.getRootView().getWidth())
38 | .setDuration(getRemoveDuration())
39 | .setListener(new DefaultRemoveVpaListener(holder))
40 | .setStartDelay(getRemoveDelay(holder))
41 | .start();
42 | }
43 |
44 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
45 | ViewCompat.setTranslationX(holder.itemView, -holder.itemView.getRootView().getWidth());
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .translationX(0)
51 | .setDuration(getAddDuration())
52 | .setListener(new DefaultAddVpaListener(holder))
53 | .setInterpolator(new OvershootInterpolator(mTension))
54 | .setStartDelay(getAddDelay(holder))
55 | .start();
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/OvershootInRightAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.OvershootInterpolator;
22 |
23 | public class OvershootInRightAnimator extends BaseItemAnimator {
24 |
25 | private final float mTension;
26 |
27 | public OvershootInRightAnimator() {
28 | mTension = 2.0f;
29 | }
30 |
31 | public OvershootInRightAnimator(float mTension) {
32 | this.mTension = mTension;
33 | }
34 |
35 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
36 | ViewCompat.animate(holder.itemView)
37 | .translationX(holder.itemView.getRootView().getWidth())
38 | .setDuration(getRemoveDuration())
39 | .setListener(new DefaultRemoveVpaListener(holder))
40 | .setStartDelay(getRemoveDelay(holder))
41 | .start();
42 | }
43 |
44 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
45 | ViewCompat.setTranslationX(holder.itemView, holder.itemView.getRootView().getWidth());
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .translationX(0)
51 | .setDuration(getAddDuration())
52 | .setInterpolator(new OvershootInterpolator(mTension))
53 | .setListener(new DefaultAddVpaListener(holder))
54 | .setStartDelay(getAddDelay(holder))
55 | .start();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/ScaleInAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class ScaleInAnimator extends BaseItemAnimator {
24 |
25 | public ScaleInAnimator() {
26 | }
27 |
28 | public ScaleInAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
33 | ViewCompat.animate(holder.itemView)
34 | .scaleX(0)
35 | .scaleY(0)
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setScaleX(holder.itemView, 0);
45 | ViewCompat.setScaleY(holder.itemView, 0);
46 | }
47 |
48 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
49 | ViewCompat.animate(holder.itemView)
50 | .scaleX(1)
51 | .scaleY(1)
52 | .setDuration(getAddDuration())
53 | .setInterpolator(mInterpolator)
54 | .setListener(new DefaultAddVpaListener(holder))
55 | .setStartDelay(getAddDelay(holder))
56 | .start();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/ScaleInBottomAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class ScaleInBottomAnimator extends BaseItemAnimator {
24 |
25 | public ScaleInBottomAnimator() {
26 | }
27 |
28 | public ScaleInBottomAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
33 | // @TODO https://code.google.com/p/android/issues/detail?id=80863
34 | // ViewCompat.setPivotY(holder.itemView, holder.itemView.getHeight());
35 | holder.itemView.setPivotY(holder.itemView.getHeight());
36 | }
37 |
38 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
39 | ViewCompat.animate(holder.itemView)
40 | .scaleX(0)
41 | .scaleY(0)
42 | .setDuration(getRemoveDuration())
43 | .setInterpolator(mInterpolator)
44 | .setListener(new DefaultRemoveVpaListener(holder))
45 | .setStartDelay(getRemoveDelay(holder))
46 | .start();
47 | }
48 |
49 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
50 | // @TODO https://code.google.com/p/android/issues/detail?id=80863
51 | // ViewCompat.setPivotY(holder.itemView, holder.itemView.getHeight());
52 | holder.itemView.setPivotY(holder.itemView.getHeight());
53 | ViewCompat.setScaleX(holder.itemView, 0);
54 | ViewCompat.setScaleY(holder.itemView, 0);
55 | }
56 |
57 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
58 | ViewCompat.animate(holder.itemView)
59 | .scaleX(1)
60 | .scaleY(1)
61 | .setDuration(getAddDuration())
62 | .setInterpolator(mInterpolator)
63 | .setListener(new DefaultAddVpaListener(holder))
64 | .setStartDelay(getAddDelay(holder))
65 | .start();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/ScaleInLeftAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class ScaleInLeftAnimator extends BaseItemAnimator {
24 |
25 | public ScaleInLeftAnimator() {
26 | }
27 |
28 | public ScaleInLeftAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
33 | ViewCompat.setPivotX(holder.itemView, 0);
34 | }
35 |
36 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
37 | ViewCompat.animate(holder.itemView)
38 | .scaleX(0)
39 | .scaleY(0)
40 | .setDuration(getRemoveDuration())
41 | .setInterpolator(mInterpolator)
42 | .setListener(new DefaultRemoveVpaListener(holder))
43 | .setStartDelay(getRemoveDelay(holder))
44 | .start();
45 | }
46 |
47 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
48 | ViewCompat.setPivotX(holder.itemView, 0);
49 | ViewCompat.setScaleX(holder.itemView, 0);
50 | ViewCompat.setScaleY(holder.itemView, 0);
51 | }
52 |
53 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
54 | ViewCompat.animate(holder.itemView)
55 | .scaleX(1)
56 | .scaleY(1)
57 | .setDuration(getAddDuration())
58 | .setInterpolator(mInterpolator)
59 | .setListener(new DefaultAddVpaListener(holder))
60 | .setStartDelay(getAddDelay(holder))
61 | .start();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/ScaleInRightAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class ScaleInRightAnimator extends BaseItemAnimator {
24 |
25 | public ScaleInRightAnimator() {
26 | }
27 |
28 | public ScaleInRightAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
33 | ViewCompat.setPivotX(holder.itemView, holder.itemView.getWidth());
34 | }
35 |
36 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
37 | ViewCompat.animate(holder.itemView)
38 | .scaleX(0)
39 | .scaleY(0)
40 | .setDuration(getRemoveDuration())
41 | .setInterpolator(mInterpolator)
42 | .setListener(new DefaultRemoveVpaListener(holder))
43 | .setStartDelay(getRemoveDelay(holder))
44 | .start();
45 | }
46 |
47 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
48 | ViewCompat.setPivotX(holder.itemView, holder.itemView.getWidth());
49 | ViewCompat.setScaleX(holder.itemView, 0);
50 | ViewCompat.setScaleY(holder.itemView, 0);
51 | }
52 |
53 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
54 | ViewCompat.animate(holder.itemView)
55 | .scaleX(1)
56 | .scaleY(1)
57 | .setDuration(getAddDuration())
58 | .setInterpolator(mInterpolator)
59 | .setListener(new DefaultAddVpaListener(holder))
60 | .setStartDelay(getAddDelay(holder))
61 | .start();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/ScaleInTopAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class ScaleInTopAnimator extends BaseItemAnimator {
24 |
25 | public ScaleInTopAnimator() {
26 | }
27 |
28 | public ScaleInTopAnimator(Interpolator interpolator) {
29 | mInterpolator = interpolator;
30 | }
31 |
32 | @Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
33 | // @TODO https://code.google.com/p/android/issues/detail?id=80863
34 | // ViewCompat.setPivotY(holder.itemView, 0);
35 | holder.itemView.setPivotY(0);
36 | }
37 |
38 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
39 | ViewCompat.animate(holder.itemView)
40 | .scaleX(0)
41 | .scaleY(0)
42 | .setDuration(getRemoveDuration())
43 | .setInterpolator(mInterpolator)
44 | .setListener(new DefaultRemoveVpaListener(holder))
45 | .setStartDelay(getRemoveDelay(holder))
46 | .start();
47 | }
48 |
49 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
50 | // @TODO https://code.google.com/p/android/issues/detail?id=80863
51 | // ViewCompat.setPivotY(holder.itemView, 0);
52 | holder.itemView.setPivotY(0);
53 | ViewCompat.setScaleX(holder.itemView, 0);
54 | ViewCompat.setScaleY(holder.itemView, 0);
55 | }
56 |
57 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
58 | ViewCompat.animate(holder.itemView)
59 | .scaleX(1)
60 | .scaleY(1)
61 | .setDuration(getAddDuration())
62 | .setInterpolator(mInterpolator)
63 | .setListener(new DefaultAddVpaListener(holder))
64 | .setStartDelay(getAddDelay(holder))
65 | .start();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/SlideInDownAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class SlideInDownAnimator extends BaseItemAnimator {
24 |
25 | public SlideInDownAnimator() {
26 |
27 | }
28 |
29 | public SlideInDownAnimator(Interpolator interpolator) {
30 | mInterpolator = interpolator;
31 | }
32 |
33 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
34 | ViewCompat.animate(holder.itemView)
35 | .translationY(-holder.itemView.getHeight())
36 | .alpha(0)
37 | .setDuration(getRemoveDuration())
38 | .setInterpolator(mInterpolator)
39 | .setListener(new DefaultRemoveVpaListener(holder))
40 | .setStartDelay(getRemoveDelay(holder))
41 | .start();
42 | }
43 |
44 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
45 | ViewCompat.setTranslationY(holder.itemView, -holder.itemView.getHeight());
46 | ViewCompat.setAlpha(holder.itemView, 0);
47 | }
48 |
49 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
50 | ViewCompat.animate(holder.itemView)
51 | .translationY(0)
52 | .alpha(1)
53 | .setDuration(getAddDuration())
54 | .setInterpolator(mInterpolator)
55 | .setListener(new DefaultAddVpaListener(holder))
56 | .setStartDelay(getAddDelay(holder))
57 | .start();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/SlideInLeftAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class SlideInLeftAnimator extends BaseItemAnimator {
24 |
25 | public SlideInLeftAnimator() {
26 |
27 | }
28 |
29 | public SlideInLeftAnimator(Interpolator interpolator) {
30 | mInterpolator = interpolator;
31 | }
32 |
33 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
34 | ViewCompat.animate(holder.itemView)
35 | .translationX(-holder.itemView.getRootView().getWidth())
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setTranslationX(holder.itemView, -holder.itemView.getRootView().getWidth());
45 | }
46 |
47 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
48 | ViewCompat.animate(holder.itemView)
49 | .translationX(0)
50 | .setDuration(getAddDuration())
51 | .setInterpolator(mInterpolator)
52 | .setListener(new DefaultAddVpaListener(holder))
53 | .setStartDelay(getAddDelay(holder))
54 | .start();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/SlideInRightAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class SlideInRightAnimator extends BaseItemAnimator {
24 |
25 | public SlideInRightAnimator() {
26 |
27 | }
28 |
29 | public SlideInRightAnimator(Interpolator interpolator) {
30 | mInterpolator = interpolator;
31 | }
32 |
33 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
34 | ViewCompat.animate(holder.itemView)
35 | .translationX(holder.itemView.getRootView().getWidth())
36 | .setDuration(getRemoveDuration())
37 | .setInterpolator(mInterpolator)
38 | .setListener(new DefaultRemoveVpaListener(holder))
39 | .setStartDelay(getRemoveDelay(holder))
40 | .start();
41 | }
42 |
43 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
44 | ViewCompat.setTranslationX(holder.itemView, holder.itemView.getRootView().getWidth());
45 | }
46 |
47 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
48 | ViewCompat.animate(holder.itemView)
49 | .translationX(0)
50 | .setDuration(getAddDuration())
51 | .setInterpolator(mInterpolator)
52 | .setListener(new DefaultAddVpaListener(holder))
53 | .setStartDelay(getAddDelay(holder))
54 | .start();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/SlideInUpAnimator.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators;
2 |
3 | /**
4 | * Copyright (C) 2015 Wasabeef
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | import android.support.v4.view.ViewCompat;
20 | import android.support.v7.widget.RecyclerView;
21 | import android.view.animation.Interpolator;
22 |
23 | public class SlideInUpAnimator extends BaseItemAnimator {
24 |
25 | public SlideInUpAnimator() {
26 |
27 | }
28 |
29 | public SlideInUpAnimator(Interpolator interpolator) {
30 | mInterpolator = interpolator;
31 | }
32 |
33 | @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
34 | ViewCompat.animate(holder.itemView)
35 | .translationY(holder.itemView.getHeight())
36 | .alpha(0)
37 | .setDuration(getRemoveDuration())
38 | .setInterpolator(mInterpolator)
39 | .setListener(new DefaultRemoveVpaListener(holder))
40 | .setStartDelay(getRemoveDelay(holder))
41 | .start();
42 | }
43 |
44 | @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
45 | ViewCompat.setTranslationY(holder.itemView, holder.itemView.getHeight());
46 | ViewCompat.setAlpha(holder.itemView, 0);
47 | }
48 |
49 | @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
50 | ViewCompat.animate(holder.itemView)
51 | .translationY(0)
52 | .alpha(1)
53 | .setDuration(getAddDuration())
54 | .setInterpolator(mInterpolator)
55 | .setListener(new DefaultAddVpaListener(holder))
56 | .setStartDelay(getAddDelay(holder))
57 | .start();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/animators/holder/AnimateViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.marshon.animators.holder;
2 |
3 | import android.support.v4.view.ViewPropertyAnimatorListener;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.View;
6 |
7 | public abstract class AnimateViewHolder extends RecyclerView.ViewHolder {
8 |
9 | public AnimateViewHolder(View itemView) {
10 | super(itemView);
11 | }
12 |
13 | public void preAnimateAddImpl() {
14 | }
15 |
16 | public void preAnimateRemoveImpl() {
17 | }
18 |
19 | public abstract void animateAddImpl(ViewPropertyAnimatorListener listener);
20 |
21 | public abstract void animateRemoveImpl(ViewPropertyAnimatorListener listener);
22 | }
23 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/internal/ViewHelper.java:
--------------------------------------------------------------------------------
1 | package com.marshon.internal;
2 |
3 | import android.support.v4.view.ViewCompat;
4 | import android.view.View;
5 |
6 | /**
7 | * Copyright (C) 2015 Wasabeef
8 | *
9 | * Licensed under the Apache License, Version 2.0 (the "License");
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an "AS IS" BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | */
21 |
22 | public final class ViewHelper {
23 |
24 | public static void clear(View v) {
25 | ViewCompat.setAlpha(v, 1);
26 | ViewCompat.setScaleY(v, 1);
27 | ViewCompat.setScaleX(v, 1);
28 | ViewCompat.setTranslationY(v, 0);
29 | ViewCompat.setTranslationX(v, 0);
30 | ViewCompat.setRotation(v, 0);
31 | ViewCompat.setRotationY(v, 0);
32 | ViewCompat.setRotationX(v, 0);
33 | ViewCompat.setPivotY(v, v.getMeasuredHeight() / 2);
34 | ViewCompat.setPivotX(v, v.getMeasuredWidth() / 2);
35 | ViewCompat.animate(v).setInterpolator(null).setStartDelay(0);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/mrecyclerview/ArrowRefreshHeader.java:
--------------------------------------------------------------------------------
1 | package com.marshon.mrecyclerview;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.os.Handler;
6 | import android.util.AttributeSet;
7 | import android.view.Gravity;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.animation.Animation;
12 | import android.view.animation.RotateAnimation;
13 | import android.widget.ImageView;
14 | import android.widget.LinearLayout;
15 | import android.widget.ProgressBar;
16 | import android.widget.TextView;
17 |
18 | import com.marshon.mrecyclerview.R;
19 |
20 | import java.util.Date;
21 |
22 | public class ArrowRefreshHeader extends LinearLayout implements BaseRefreshHeader{
23 | private LinearLayout mContainer;
24 | private ImageView mArrowImageView;
25 | private SimpleViewSwithcer mProgressBar;
26 | private TextView mStatusTextView;
27 | private int mState = STATE_NORMAL;
28 | private Context mContext;
29 |
30 | private TextView mHeaderTimeView;
31 |
32 | private Animation mRotateUpAnim;
33 | private Animation mRotateDownAnim;
34 |
35 | private final int ROTATE_ANIM_DURATION = 180;
36 |
37 | public int mMeasuredHeight;
38 | private float maxPullHeight = 400;
39 |
40 | public ArrowRefreshHeader(Context context) {
41 | super(context);
42 | initView(context);
43 | }
44 |
45 | /**
46 | * @param context
47 | * @param attrs
48 | */
49 | public ArrowRefreshHeader(Context context, AttributeSet attrs) {
50 | super(context, attrs);
51 | initView(context);
52 | }
53 |
54 | private void initView(Context context) {
55 |
56 | mContext = context;
57 | // 初始情况,设置下拉刷新view高度为0
58 | mContainer = (LinearLayout) LayoutInflater.from(context).inflate(
59 | R.layout.listview_header, null);
60 | LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
61 | lp.setMargins(0, 0, 0, 0);
62 | this.setLayoutParams(lp);
63 | this.setPadding(0, 0, 0, 0);
64 |
65 | addView(mContainer, new LayoutParams(LayoutParams.MATCH_PARENT, 0));
66 | setGravity(Gravity.BOTTOM);
67 |
68 |
69 | mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow);
70 | mStatusTextView = (TextView)findViewById(R.id.refresh_status_textview);
71 |
72 | //init the progress view
73 | mProgressBar = (SimpleViewSwithcer)findViewById(R.id.listview_header_progressbar);
74 |
75 |
76 | ProgressBar progressBar=new ProgressBar(context, null, android.R.attr.progressBarStyle);
77 | progressBar.setIndeterminate(true);
78 |
79 | mProgressBar.setView(progressBar);
80 |
81 |
82 | mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
83 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
84 | 0.5f);
85 | mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
86 | mRotateUpAnim.setFillAfter(true);
87 | mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
88 | Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
89 | 0.5f);
90 | mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
91 | mRotateDownAnim.setFillAfter(true);
92 |
93 | mHeaderTimeView = (TextView)findViewById(R.id.last_refresh_time);
94 | measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
95 | mMeasuredHeight = getMeasuredHeight();
96 | }
97 |
98 | public void setProgressStyle(int style) {
99 | // if(style == ProgressStyle.SysProgress){
100 | mProgressBar.setView(new ProgressBar(mContext, null, android.R.attr.progressBarStyle));
101 | // }else{
102 | // AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext());
103 | // progressView.setIndicatorColor(0xffB5B5B5);
104 | // progressView.setIndicatorId(style);
105 | // mProgressBar.setView(progressView);
106 | // }
107 | }
108 |
109 | public void setArrowImageView(int resid){
110 | mArrowImageView.setImageResource(resid);
111 | }
112 |
113 | public void setState(int state) {
114 | if (state == mState) return ;
115 |
116 | if (state == STATE_REFRESHING) { // 显示进度
117 | mArrowImageView.clearAnimation();
118 | mArrowImageView.setVisibility(View.INVISIBLE);
119 | mProgressBar.setVisibility(View.VISIBLE);
120 | } else if(state == STATE_DONE) {
121 | mArrowImageView.setVisibility(View.INVISIBLE);
122 | mProgressBar.setVisibility(View.INVISIBLE);
123 | } else { // 显示箭头图片
124 | mArrowImageView.setVisibility(View.VISIBLE);
125 | mProgressBar.setVisibility(View.INVISIBLE);
126 | }
127 |
128 | switch(state){
129 | case STATE_NORMAL:
130 | if (mState == STATE_RELEASE_TO_REFRESH) {
131 | mArrowImageView.startAnimation(mRotateDownAnim);
132 | }
133 | if (mState == STATE_REFRESHING) {
134 | mArrowImageView.clearAnimation();
135 | }
136 | mStatusTextView.setText(R.string.listview_header_hint_normal);
137 | break;
138 | case STATE_RELEASE_TO_REFRESH:
139 | if (mState != STATE_RELEASE_TO_REFRESH) {
140 | mArrowImageView.clearAnimation();
141 | mArrowImageView.startAnimation(mRotateUpAnim);
142 | mStatusTextView.setText(R.string.listview_header_hint_release);
143 | }
144 | break;
145 | case STATE_REFRESHING:
146 | mStatusTextView.setText(R.string.refreshing);
147 | break;
148 | case STATE_DONE:
149 | mStatusTextView.setText(R.string.refresh_done);
150 | break;
151 | default:
152 | }
153 |
154 | mState = state;
155 | }
156 |
157 | public int getState() {
158 | return mState;
159 | }
160 |
161 | @Override
162 | public void refreshComplate(){
163 | mHeaderTimeView.setText(friendlyTime(new Date()));
164 | setState(STATE_DONE);
165 | new Handler().postDelayed(new Runnable() {
166 | public void run() {
167 | reset();
168 | }
169 | }, 200);
170 | }
171 |
172 | public void setVisiableHeight(int height) {
173 | if (height < 0)
174 | height = 0;
175 | if (height>400)
176 | height= (int) (maxPullHeight-0.5f);
177 |
178 | LayoutParams lp = (LayoutParams) mContainer
179 | .getLayoutParams();
180 | lp.height = height;
181 |
182 | mContainer.setLayoutParams(lp);
183 |
184 | //计算百分比
185 | // float rate = height / maxPullHeight;
186 | // if (scalerIMG!=null){
187 | // scalerIMG.setScaleY(1.0f+rate);
188 | // scalerIMG.setScaleX(1.0f+rate);
189 | // }
190 |
191 | }
192 |
193 | public int getVisiableHeight() {
194 | int height = 0;
195 | LayoutParams lp = (LayoutParams) mContainer
196 | .getLayoutParams();
197 | height = lp.height;
198 | return height;
199 | }
200 |
201 | @Override
202 | public void onMove(float delta) {
203 | if(getVisiableHeight() > 0 || delta > 0) {
204 | setVisiableHeight((int) delta + getVisiableHeight());
205 | if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态,更新箭头
206 | if (getVisiableHeight() > mMeasuredHeight) {
207 | setState(STATE_RELEASE_TO_REFRESH);
208 | }else {
209 | setState(STATE_NORMAL);
210 | }
211 | }
212 | }
213 | }
214 |
215 | @Override
216 | public boolean releaseAction() {
217 | boolean isOnRefresh = false;
218 | int height = getVisiableHeight();
219 | if (height == 0) // not visible.
220 | isOnRefresh = false;
221 |
222 | if(getVisiableHeight() > mMeasuredHeight && mState < STATE_REFRESHING){
223 | setState(STATE_REFRESHING);
224 | isOnRefresh = true;
225 | }
226 | // refreshing and header isn't shown fully. do nothing.
227 | if (mState == STATE_REFRESHING && height <= mMeasuredHeight) {
228 | //return;
229 | }
230 | int destHeight = 0; // default: scroll back to dismiss header.
231 | // is refreshing, just scroll back to show all the header.
232 | if (mState == STATE_REFRESHING) {
233 | destHeight = mMeasuredHeight;
234 | }
235 | smoothScrollTo(destHeight);
236 |
237 | return isOnRefresh;
238 | }
239 |
240 | public void reset() {
241 | smoothScrollTo(0);
242 | new Handler().postDelayed(new Runnable() {
243 | public void run() {
244 | setState(STATE_NORMAL);
245 | }
246 | }, 500);
247 | }
248 |
249 | private void smoothScrollTo(int destHeight) {
250 | ValueAnimator animator = ValueAnimator.ofInt(getVisiableHeight(), destHeight);
251 | animator.setDuration(300).start();
252 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
253 | @Override
254 | public void onAnimationUpdate(ValueAnimator animation)
255 | {
256 | setVisiableHeight((int) animation.getAnimatedValue());
257 | }
258 | });
259 | animator.start();
260 | }
261 |
262 | public static String friendlyTime(Date time) {
263 | //获取time距离当前的秒数
264 | int ct = (int)((System.currentTimeMillis() - time.getTime())/1000);
265 |
266 | if(ct == 0) {
267 | return "刚刚";
268 | }
269 |
270 | if(ct > 0 && ct < 60) {
271 | return ct + "秒前";
272 | }
273 |
274 | if(ct >= 60 && ct < 3600) {
275 | return Math.max(ct / 60,1) + "分钟前";
276 | }
277 | if(ct >= 3600 && ct < 86400)
278 | return ct / 3600 + "小时前";
279 | if(ct >= 86400 && ct < 2592000){ //86400 * 30
280 | int day = ct / 86400 ;
281 | return day + "天前";
282 | }
283 | if(ct >= 2592000 && ct < 31104000) { //86400 * 30
284 | return ct / 2592000 + "月前";
285 | }
286 | return ct / 31104000 + "年前";
287 | }
288 |
289 | }
290 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/mrecyclerview/BaseRefreshHeader.java:
--------------------------------------------------------------------------------
1 | package com.marshon.mrecyclerview;
2 |
3 | /**
4 | * Created by jianghejie on 15/11/22.
5 | */
6 | interface BaseRefreshHeader {
7 | public void onMove(float delta) ;
8 | public boolean releaseAction();
9 | public void refreshComplate();
10 | public final static int STATE_NORMAL = 0;
11 | public final static int STATE_RELEASE_TO_REFRESH = 1;
12 | public final static int STATE_REFRESHING = 2;
13 | public final static int STATE_DONE = 3;
14 | }
15 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/mrecyclerview/JellyView.java:
--------------------------------------------------------------------------------
1 | package com.marshon.mrecyclerview;
2 |
3 | /**
4 | * Created by jianghejie on 15/11/22.
5 | */
6 |
7 | import android.annotation.TargetApi;
8 | import android.content.Context;
9 | import android.graphics.Canvas;
10 | import android.graphics.Paint;
11 | import android.graphics.Path;
12 | import android.os.Build;
13 | import android.util.AttributeSet;
14 | import android.util.Log;
15 | import android.view.View;
16 |
17 |
18 | public class JellyView extends View implements BaseRefreshHeader{
19 | Path path;
20 |
21 | Paint paint;
22 |
23 | private int minimumHeight = 0;
24 |
25 | private int jellyHeight =0;
26 |
27 | public JellyView(Context context) {
28 | super(context);
29 | init();
30 | }
31 |
32 | public JellyView(Context context, AttributeSet attrs) {
33 | super(context, attrs);
34 | init();
35 | }
36 |
37 | public JellyView(Context context, AttributeSet attrs, int defStyleAttr) {
38 | super(context, attrs, defStyleAttr);
39 | init();
40 | }
41 |
42 | @SuppressWarnings("unused")
43 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
44 | public JellyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
45 | super(context, attrs, defStyleAttr, defStyleRes);
46 | init();
47 | }
48 |
49 | private void init() {
50 | if (isInEditMode()) {
51 | return;
52 | }
53 | path = new Path();
54 | paint = new Paint();
55 | paint.setColor(getContext().getResources().getColor(android.R.color.holo_blue_bright));
56 | paint.setAntiAlias(true);
57 | }
58 |
59 | public void setJellyColor(int jellyColor) {
60 | paint.setColor(jellyColor);
61 | }
62 |
63 | @Override
64 | protected void onDraw(Canvas canvas) {
65 | super.onDraw(canvas);
66 | path.reset();
67 | path.lineTo(0, minimumHeight);
68 | path.quadTo(getMeasuredWidth() / 2, minimumHeight + jellyHeight, getMeasuredWidth(), minimumHeight);
69 | path.lineTo(getMeasuredWidth(), 0);
70 | canvas.drawPath(path, paint);
71 | }
72 |
73 | @Override
74 | public void setMinimumHeight(int minimumHeight) {
75 | this.minimumHeight = minimumHeight;
76 | }
77 |
78 | public void setJellyHeight(int ribbonHeight) {
79 | this.jellyHeight = ribbonHeight;
80 | }
81 |
82 | @Override
83 | public int getMinimumHeight() {
84 | return minimumHeight;
85 | }
86 |
87 | public int getJellyHeight() {
88 | return jellyHeight;
89 | }
90 |
91 |
92 | @Override
93 | public void refreshComplate(){
94 |
95 | }
96 |
97 | @Override
98 | public void onMove(float delta) {
99 | jellyHeight = jellyHeight + (int)delta;
100 | Log.i("jellyHeight", "delta = " + delta);
101 | this.invalidate();
102 | }
103 |
104 | @Override
105 | public boolean releaseAction() {
106 | return false;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/mrecyclerview/LoadingMoreFooter.java:
--------------------------------------------------------------------------------
1 | package com.marshon.mrecyclerview;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.Gravity;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.LinearLayout;
9 | import android.widget.ProgressBar;
10 | import android.widget.TextView;
11 |
12 | import com.marshon.mrecyclerview.R;
13 |
14 |
15 | public class LoadingMoreFooter extends LinearLayout {
16 |
17 | private SimpleViewSwithcer progressCon;
18 | private Context mContext;
19 | public final static int STATE_LOADING = 0;
20 | public final static int STATE_COMPLETE = 1;
21 | public final static int STATE_NOMORE = 2;
22 | private TextView mText;
23 | public LoadingMoreFooter(Context context) {
24 | super(context);
25 | initView(context);
26 | }
27 |
28 | /**
29 | * @param context
30 | * @param attrs
31 | */
32 | public LoadingMoreFooter(Context context, AttributeSet attrs) {
33 | super(context, attrs);
34 | initView(context);
35 | }
36 | public void initView(Context context ){
37 | mContext = context;
38 | setGravity(Gravity.CENTER);
39 | setLayoutParams(new ViewGroup.LayoutParams(
40 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
41 | progressCon = new SimpleViewSwithcer(context);
42 | progressCon.setLayoutParams(new ViewGroup.LayoutParams(
43 | ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
44 |
45 | ProgressBar progressBar=new ProgressBar(context, null, android.R.attr.progressBarStyle);
46 | progressBar.setIndeterminate(true);
47 | progressCon.setView(progressBar);
48 |
49 | addView(progressCon);
50 | mText = new TextView(context);
51 | mText.setText("正在加载...");
52 |
53 | LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
54 | layoutParams.setMargins( (int)getResources().getDimension(R.dimen.textandiconmargin),0,0,0 );
55 |
56 | mText.setLayoutParams(layoutParams);
57 | addView(mText);
58 | }
59 |
60 | public void setProgressStyle(int style) {
61 | // if(style == ProgressStyle.SysProgress){
62 | progressCon.setView(new ProgressBar(mContext, null, android.R.attr.progressBarStyle));
63 | // }else{
64 | // AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext());
65 | // progressView.setIndicatorColor(0xffB5B5B5);
66 | // progressView.setIndicatorId(style);
67 | // progressCon.setView(progressView);
68 | // }
69 | }
70 |
71 | public void setState(int state) {
72 | switch(state) {
73 | case STATE_LOADING:
74 | progressCon.setVisibility(View.VISIBLE);
75 | mText.setText(mContext.getText(R.string.listview_loading));
76 | this.setVisibility(View.VISIBLE);
77 | break;
78 | case STATE_COMPLETE:
79 | mText.setText(mContext.getText(R.string.listview_loading));
80 | this.setVisibility(View.GONE);
81 | break;
82 | case STATE_NOMORE:
83 | mText.setText(mContext.getText(R.string.nomore_loading));
84 | progressCon.setVisibility(View.GONE);
85 | this.setVisibility(View.VISIBLE);
86 | break;
87 | }
88 |
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/mrecyclerview/MRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.marshon.mrecyclerview;
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.util.Log;
10 | import android.view.MotionEvent;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | public class MRecyclerView extends RecyclerView {
18 |
19 | private Context mContext;
20 | private boolean isLoadingData = false;
21 | private boolean isnomore = false;
22 | private int mRefreshProgressStyle =1;
23 | private int mLoadingMoreProgressStyle = 1;
24 | private ArrayList mHeaderViews = new ArrayList<>();
25 | private ArrayList mFootViews = new ArrayList<>();
26 | private Adapter mAdapter;
27 | private Adapter mWrapAdapter;
28 | private float mLastY = -1;
29 | private static final float DRAG_RATE = 3;
30 | private LoadingListener mLoadingListener;
31 | private ArrowRefreshHeader mRefreshHeader;
32 | private boolean pullRefreshEnabled = true;
33 | private boolean loadingMoreEnabled = true;
34 | private static final int TYPE_REFRESH_HEADER = -5;
35 | private static final int TYPE_NORMAL = 0;
36 | private static final int TYPE_FOOTER = -3;
37 | private static final int HEADER_INIT_INDEX = 10000;
38 | private static List sHeaderTypes = new ArrayList<>();
39 | private int mPageCount = 0;
40 | //adapter没有数据的时候显示,类似于listView的emptyView
41 | private View mEmptyView;
42 |
43 | public MRecyclerView(Context context) {
44 | this(context, null);
45 | }
46 |
47 | public MRecyclerView(Context context, AttributeSet attrs) {
48 | this(context, attrs, 0);
49 | }
50 |
51 | public MRecyclerView(Context context, AttributeSet attrs, int defStyle) {
52 | super(context, attrs, defStyle);
53 | init(context);
54 | }
55 |
56 | private void init(Context context) {
57 | mContext = context;
58 | if (pullRefreshEnabled) {
59 | ArrowRefreshHeader refreshHeader = new ArrowRefreshHeader(mContext);
60 | mHeaderViews.add(0, refreshHeader);
61 | mRefreshHeader = refreshHeader;
62 | mRefreshHeader.setProgressStyle(mRefreshProgressStyle);
63 | }
64 | LoadingMoreFooter footView = new LoadingMoreFooter(mContext);
65 | footView.setProgressStyle(mLoadingMoreProgressStyle);
66 | addFootView(footView);
67 | mFootViews.get(0).setVisibility(GONE);
68 | }
69 |
70 | public void addHeaderView(View view) {
71 | if (pullRefreshEnabled && !(mHeaderViews.get(0) instanceof ArrowRefreshHeader)) {
72 | ArrowRefreshHeader refreshHeader = new ArrowRefreshHeader(mContext);
73 | mHeaderViews.add(0, refreshHeader);
74 | mRefreshHeader = refreshHeader;
75 | mRefreshHeader.setProgressStyle(mRefreshProgressStyle);
76 | }
77 | mHeaderViews.add(view);
78 | sHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size());
79 | }
80 |
81 | public void addFootView(final View view) {
82 | mFootViews.clear();
83 | mFootViews.add(view);
84 | }
85 |
86 | public void loadMoreComplete() {
87 | isLoadingData = false;
88 | View footView = mFootViews.get(0);
89 | if (footView instanceof LoadingMoreFooter) {
90 | ((LoadingMoreFooter) footView).setState(LoadingMoreFooter.STATE_COMPLETE);
91 | } else {
92 | footView.setVisibility(View.GONE);
93 | }
94 |
95 | }
96 |
97 | public void setIsnomore(boolean isnomore){
98 | this.isnomore = isnomore;
99 | View footView = mFootViews.get(0);
100 | ((LoadingMoreFooter) footView).setState(this.isnomore ? LoadingMoreFooter.STATE_NOMORE:LoadingMoreFooter.STATE_COMPLETE);
101 | }
102 | public void reset(){
103 | setIsnomore(false);
104 | loadMoreComplete();
105 | refreshComplete();
106 | }
107 |
108 | public void noMoreLoading() {
109 | isLoadingData = false;
110 | View footView = mFootViews.get(0);
111 | isnomore = true;
112 | if (footView instanceof LoadingMoreFooter) {
113 | ((LoadingMoreFooter) footView).setState(LoadingMoreFooter.STATE_NOMORE);
114 | } else {
115 | footView.setVisibility(View.GONE);
116 | }
117 | }
118 |
119 | public void refreshComplete() {
120 | mRefreshHeader.refreshComplate();
121 | }
122 |
123 | public void setRefreshHeader(ArrowRefreshHeader refreshHeader) {
124 | mRefreshHeader = refreshHeader;
125 | }
126 |
127 | public void setPullRefreshEnabled(boolean enabled) {
128 | pullRefreshEnabled = enabled;
129 | }
130 |
131 | public void setLoadingMoreEnabled(boolean enabled) {
132 | loadingMoreEnabled = enabled;
133 | if (!enabled) {
134 | if (mFootViews.size() > 0) {
135 | mFootViews.get(0).setVisibility(GONE);
136 | }
137 | }
138 | }
139 |
140 | public void setRefreshProgressStyle(int style) {
141 | mRefreshProgressStyle = style;
142 | if (mRefreshHeader != null) {
143 | mRefreshHeader.setProgressStyle(style);
144 | }
145 | }
146 |
147 | public void setLoadingMoreProgressStyle(int style) {
148 | mLoadingMoreProgressStyle = style;
149 | if (mFootViews.size() > 0 && mFootViews.get(0) instanceof LoadingMoreFooter) {
150 | ((LoadingMoreFooter) mFootViews.get(0)).setProgressStyle(style);
151 | }
152 | }
153 |
154 | public void setArrowImageView(int resid) {
155 | if (mRefreshHeader != null) {
156 | mRefreshHeader.setArrowImageView(resid);
157 | }
158 | }
159 |
160 | public void setEmptyView(View emptyView) {
161 | this.mEmptyView = emptyView;
162 | mDataObserver.onChanged();
163 | }
164 |
165 | public View getEmptyView() {
166 | return mEmptyView;
167 | }
168 |
169 | @Override
170 | public void setAdapter(Adapter adapter) {
171 | mAdapter = adapter;
172 | mWrapAdapter = new WrapAdapter(mHeaderViews, mFootViews, adapter);
173 | super.setAdapter(mWrapAdapter);
174 | mAdapter.registerAdapterDataObserver(mDataObserver);
175 | mDataObserver.onChanged();
176 | }
177 |
178 | @Override
179 | public void onScrollStateChanged(int state) {
180 | super.onScrollStateChanged(state);
181 |
182 | if (state == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) {
183 | LayoutManager layoutManager = getLayoutManager();
184 | int lastVisibleItemPosition;
185 | if (layoutManager instanceof GridLayoutManager) {
186 | lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
187 | } else if (layoutManager instanceof StaggeredGridLayoutManager) {
188 | int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
189 | ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
190 | lastVisibleItemPosition = findMax(into);
191 | } else {
192 | lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
193 | }
194 | if (layoutManager.getChildCount() > 0
195 | && lastVisibleItemPosition >= layoutManager.getItemCount() - 1 && layoutManager.getItemCount() > layoutManager.getChildCount() && !isnomore && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) {
196 |
197 | View footView = mFootViews.get(0);
198 | isLoadingData = true;
199 | if (footView instanceof LoadingMoreFooter) {
200 | ((LoadingMoreFooter) footView).setState(LoadingMoreFooter.STATE_LOADING);
201 | } else {
202 | footView.setVisibility(View.VISIBLE);
203 | }
204 | mLoadingListener.onLoadMore();
205 | }
206 | }
207 | }
208 |
209 | @Override
210 | public boolean onTouchEvent(MotionEvent ev) {
211 | if (mLastY == -1) {
212 | mLastY = ev.getRawY();
213 | }
214 | switch (ev.getAction()) {
215 | case MotionEvent.ACTION_DOWN:
216 | mLastY = ev.getRawY();
217 | break;
218 | case MotionEvent.ACTION_MOVE:
219 | final float deltaY = ev.getRawY() - mLastY;
220 | mLastY = ev.getRawY();
221 | if (isOnTop() && pullRefreshEnabled) {
222 | mRefreshHeader.onMove(deltaY / DRAG_RATE);
223 | if (mRefreshHeader.getVisiableHeight() > 0 && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) {
224 | Log.i("getVisiableHeight", "getVisiableHeight = " + mRefreshHeader.getVisiableHeight());
225 | Log.i("getVisiableHeight", " mRefreshHeader.getState() = " + mRefreshHeader.getState());
226 | return false;
227 | }
228 | }
229 | break;
230 | default:
231 | mLastY = -1; // reset
232 | if (isOnTop() && pullRefreshEnabled) {
233 | if (mRefreshHeader.releaseAction()) {
234 | if (mLoadingListener != null) {
235 | mLoadingListener.onRefresh();
236 | }
237 | }
238 | }
239 | break;
240 | }
241 | return super.onTouchEvent(ev);
242 | }
243 |
244 | private int findMax(int[] lastPositions) {
245 | int max = lastPositions[0];
246 | for (int value : lastPositions) {
247 | if (value > max) {
248 | max = value;
249 | }
250 | }
251 | return max;
252 | }
253 |
254 | private int findMin(int[] firstPositions) {
255 | int min = firstPositions[0];
256 | for (int value : firstPositions) {
257 | if (value < min) {
258 | min = value;
259 | }
260 | }
261 | return min;
262 | }
263 |
264 | private boolean isOnTop() {
265 | if (mHeaderViews == null || mHeaderViews.isEmpty()) {
266 | return false;
267 | }
268 |
269 | View view = mHeaderViews.get(0);
270 | if (view.getParent() != null) {
271 | return true;
272 | } else {
273 | return false;
274 | }
275 | // LayoutManager layoutManager = getLayoutManager();
276 | // int firstVisibleItemPosition;
277 | // if (layoutManager instanceof GridLayoutManager) {
278 | // firstVisibleItemPosition = ((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();
279 | // } else if ( layoutManager instanceof StaggeredGridLayoutManager ) {
280 | // int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
281 | // ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(into);
282 | // firstVisibleItemPosition = findMin(into);
283 | // } else {
284 | // firstVisibleItemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
285 | // }
286 | // if ( firstVisibleItemPosition <= 1 ) {
287 | // return true;
288 | // }
289 | // return false;
290 | }
291 |
292 | private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
293 | @Override
294 | public void onChanged() {
295 | Adapter> adapter = getAdapter();
296 | if (adapter != null && mEmptyView != null) {
297 | int emptyCount = 0;
298 | if (pullRefreshEnabled) {
299 | emptyCount++;
300 | }
301 | if (loadingMoreEnabled) {
302 | emptyCount++;
303 | }
304 | if (adapter.getItemCount() == emptyCount) {
305 | mEmptyView.setVisibility(View.VISIBLE);
306 | MRecyclerView.this.setVisibility(View.GONE);
307 | } else {
308 | mEmptyView.setVisibility(View.GONE);
309 | MRecyclerView.this.setVisibility(View.VISIBLE);
310 | }
311 | }
312 | if (mWrapAdapter != null) {
313 | mWrapAdapter.notifyDataSetChanged();
314 | }
315 | }
316 |
317 | @Override
318 | public void onItemRangeInserted(int positionStart, int itemCount) {
319 | mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);
320 | }
321 |
322 | @Override
323 | public void onItemRangeChanged(int positionStart, int itemCount) {
324 | mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);
325 | }
326 |
327 | @Override
328 | public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
329 | mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
330 | }
331 |
332 | @Override
333 | public void onItemRangeRemoved(int positionStart, int itemCount) {
334 | mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount);
335 | }
336 |
337 | @Override
338 | public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
339 | mWrapAdapter.notifyItemMoved(fromPosition, toPosition);
340 | }
341 | };
342 |
343 | private class WrapAdapter extends RecyclerView.Adapter {
344 |
345 | private RecyclerView.Adapter adapter;
346 |
347 | private ArrayList mHeaderViews;
348 |
349 | private ArrayList mFootViews;
350 |
351 | private int headerPosition = 1;
352 |
353 | public WrapAdapter(ArrayList headerViews, ArrayList footViews, RecyclerView.Adapter adapter) {
354 | this.adapter = adapter;
355 | this.mHeaderViews = headerViews;
356 | this.mFootViews = footViews;
357 | }
358 |
359 | @Override
360 | public void onAttachedToRecyclerView(RecyclerView recyclerView) {
361 | super.onAttachedToRecyclerView(recyclerView);
362 | RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
363 | if (manager instanceof GridLayoutManager) {
364 | final GridLayoutManager gridManager = ((GridLayoutManager) manager);
365 | gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
366 | @Override
367 | public int getSpanSize(int position) {
368 | return (isHeader(position) || isFooter(position))
369 | ? gridManager.getSpanCount() : 1;
370 | }
371 | });
372 | }
373 | }
374 |
375 | @Override
376 | public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
377 | super.onViewAttachedToWindow(holder);
378 | ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
379 | if (lp != null
380 | && lp instanceof StaggeredGridLayoutManager.LayoutParams
381 | && (isHeader(holder.getLayoutPosition()) || isFooter(holder.getLayoutPosition()))) {
382 | StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
383 | p.setFullSpan(true);
384 | }
385 | }
386 |
387 | public boolean isHeader(int position) {
388 | return position >= 0 && position < mHeaderViews.size();
389 | }
390 |
391 | public boolean isContentHeader(int position) {
392 | return position >= 1 && position < mHeaderViews.size();
393 | }
394 |
395 | public boolean isFooter(int position) {
396 | return position < getItemCount() && position >= getItemCount() - mFootViews.size();
397 | }
398 |
399 | public boolean isRefreshHeader(int position) {
400 | return position == 0;
401 | }
402 |
403 | public int getHeadersCount() {
404 | return mHeaderViews.size();
405 | }
406 |
407 | public int getFootersCount() {
408 | return mFootViews.size();
409 | }
410 |
411 | @Override
412 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
413 | if (viewType == TYPE_REFRESH_HEADER) {
414 | mCurrentPosition++;
415 | return new SimpleViewHolder(mHeaderViews.get(0));
416 | } else if (isContentHeader(mCurrentPosition)) {
417 | if (viewType == sHeaderTypes.get(mCurrentPosition - 1)) {
418 | mCurrentPosition++;
419 | return new SimpleViewHolder(mHeaderViews.get(headerPosition++));
420 | }
421 | } else if (viewType == TYPE_FOOTER) {
422 | return new SimpleViewHolder(mFootViews.get(0));
423 | }
424 | return adapter.onCreateViewHolder(parent, viewType);
425 | }
426 |
427 | private int mCurrentPosition;
428 |
429 | @Override
430 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
431 | if (isHeader(position)) {
432 | return;
433 | }
434 | int adjPosition = position - getHeadersCount();
435 | int adapterCount;
436 | if (adapter != null) {
437 | adapterCount = adapter.getItemCount();
438 | if (adjPosition < adapterCount) {
439 | adapter.onBindViewHolder(holder, adjPosition);
440 | return;
441 | }
442 | }
443 | }
444 |
445 | @Override
446 | public int getItemCount() {
447 | if (adapter != null) {
448 | return getHeadersCount() + getFootersCount() + adapter.getItemCount();
449 | } else {
450 | return getHeadersCount() + getFootersCount();
451 | }
452 | }
453 |
454 | @Override
455 | public int getItemViewType(int position) {
456 | if (isRefreshHeader(position)) {
457 | return TYPE_REFRESH_HEADER;
458 | }
459 | if (isHeader(position)) {
460 | position = position - 1;
461 | return sHeaderTypes.get(position);
462 | }
463 | if (isFooter(position)) {
464 | return TYPE_FOOTER;
465 | }
466 | int adjPosition = position - getHeadersCount();
467 | int adapterCount;
468 | if (adapter != null) {
469 | adapterCount = adapter.getItemCount();
470 | if (adjPosition < adapterCount) {
471 | return adapter.getItemViewType(adjPosition);
472 | }
473 | }
474 | return TYPE_NORMAL;
475 | }
476 |
477 | @Override
478 | public long getItemId(int position) {
479 | if (adapter != null && position >= getHeadersCount()) {
480 | int adjPosition = position - getHeadersCount();
481 | int adapterCount = adapter.getItemCount();
482 | if (adjPosition < adapterCount) {
483 | return adapter.getItemId(adjPosition);
484 | }
485 | }
486 | return -1;
487 | }
488 |
489 | @Override
490 | public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
491 | if (adapter != null) {
492 | adapter.unregisterAdapterDataObserver(observer);
493 | }
494 | }
495 |
496 | @Override
497 | public void registerAdapterDataObserver(AdapterDataObserver observer) {
498 | if (adapter != null) {
499 | adapter.registerAdapterDataObserver(observer);
500 | }
501 | }
502 |
503 | private class SimpleViewHolder extends RecyclerView.ViewHolder {
504 | public SimpleViewHolder(View itemView) {
505 | super(itemView);
506 | }
507 | }
508 | }
509 |
510 | public void setLoadingListener(LoadingListener listener) {
511 | mLoadingListener = listener;
512 | }
513 |
514 | public interface LoadingListener {
515 |
516 | void onRefresh();
517 |
518 | void onLoadMore();
519 | }
520 |
521 | public void setRefreshing(boolean refreshing) {
522 | if (refreshing && pullRefreshEnabled && mLoadingListener != null) {
523 | mRefreshHeader.setState(ArrowRefreshHeader.STATE_REFRESHING);
524 | mRefreshHeader.onMove(mRefreshHeader.getMeasuredHeight());
525 | mLoadingListener.onRefresh();
526 | }
527 | }
528 | }
529 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/java/com/marshon/mrecyclerview/SimpleViewSwithcer.java:
--------------------------------------------------------------------------------
1 | package com.marshon.mrecyclerview;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | /**
9 | * Created by jianghejie on 15/11/22.
10 | */
11 | public class SimpleViewSwithcer extends ViewGroup {
12 |
13 | public SimpleViewSwithcer(Context context) {
14 | super(context);
15 |
16 | }
17 |
18 | public SimpleViewSwithcer(Context context, AttributeSet attrs) {
19 | this(context, attrs, 0);
20 | }
21 |
22 | public SimpleViewSwithcer(Context context, AttributeSet attrs, int defStyle) {
23 | super(context, attrs, defStyle);
24 | }
25 |
26 | @Override
27 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
28 | int childCount = this.getChildCount();
29 | int maxHeight = 0;
30 | int maxWidth = 0;
31 | for (int i = 0; i < childCount; i++) {
32 | View child = this.getChildAt(i);
33 | this.measureChild(child, widthMeasureSpec, heightMeasureSpec);
34 | int cw = child.getMeasuredWidth();
35 | // int ch = child.getMeasuredHeight();
36 | maxWidth = child.getMeasuredWidth();
37 | maxHeight = child.getMeasuredHeight();
38 | }
39 | setMeasuredDimension(maxWidth, maxHeight);
40 | }
41 |
42 | @Override
43 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
44 |
45 | final int count = getChildCount();
46 |
47 | for (int i = 0; i < count; i++) {
48 | final View child = getChildAt(i);
49 | if (child.getVisibility() != View.GONE) {
50 | child.layout(0, 0, r - l, b - t);
51 |
52 | }
53 | }
54 | }
55 |
56 | public void setView(View view) {
57 | if(this.getChildCount() != 0){
58 | this.removeViewAt(0);
59 | }
60 |
61 | this.addView(view,0);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/ic_pulltorefresh_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/ic_pulltorefresh_arrow.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_01.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_02.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_03.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_04.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_05.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_06.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_07.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_08.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_09.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_10.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_11.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/loading_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/loading_12.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/progressbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/drawable-hdpi/ptrhead.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/mrecyclerview/src/main/res/drawable-hdpi/ptrhead.png
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/layout/listview_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/layout/listview_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
23 |
29 |
30 |
36 |
37 |
42 |
43 |
48 |
49 |
54 |
55 |
56 |
57 |
66 |
67 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/layout/pull_to_refresh_head.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
21 |
22 |
28 |
29 |
30 |
31 |
38 |
45 |
46 |
47 |
48 |
54 |
55 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/layout/swipe.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
19 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 下拉刷新
3 | 释放立即刷新
4 | 正在加载...
5 | 没有了
6 | 正在刷新...
7 | 刷新完成
8 | 上次更新时间:
9 |
10 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/values/attrs.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 |
--------------------------------------------------------------------------------
/mrecyclerview/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 10dp
4 |
5 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | applicationId "com.demotest.testapp"
9 | minSdkVersion 14
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:23.1.0'
25 | compile project(':mrecyclerview')
26 | // compile 'com.daimajia.swipelayout:library:1.2.0@aar'
27 | }
28 |
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\SDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/demotest/testapp/ChooseAnimatorsAdapter.java:
--------------------------------------------------------------------------------
1 | package com.demotest.testapp;
2 |
3 | import android.animation.Animator;
4 | import android.animation.ObjectAnimator;
5 | import android.animation.PropertyValuesHolder;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.View;
8 |
9 | import com.marshon.adapters.AnimationAdapter;
10 |
11 |
12 | /**
13 | * //自定义动画管理类
14 | * Created by Administrator on 2016/4/25.
15 | */
16 | public class ChooseAnimatorsAdapter extends AnimationAdapter {
17 |
18 | public static final int ANIMATORFLAG_ALPHA = 1;
19 | public static final int ANIMATORFLAG_TRANSLATION = 3;
20 | public static final int ANIMATORFLAG_SCALE = 2;
21 |
22 | private PropertyValuesHolder[] animators;
23 | private int flag = 2;
24 |
25 |
26 | public ChooseAnimatorsAdapter(RecyclerView.Adapter adapter) {
27 | super(adapter);
28 | }
29 |
30 | @Override
31 | protected Animator[] getAnimators(View view) {
32 | if (animators != null) {
33 | ObjectAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(view,animators);
34 | return new Animator[]{valueAnimator};
35 | } else {
36 | return makeAnimator(view);
37 |
38 | }
39 | }
40 |
41 | private Animator[] makeAnimator(final View view) {
42 | switch (flag) {
43 | case 1:
44 | return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", 0.1f, 1f)};
45 | case 2:
46 | return new Animator[] { ObjectAnimator.ofFloat(view, "alpha", 0.1f, 1f),ObjectAnimator.ofFloat(view, "scaleX", 0.1f, 1f),ObjectAnimator.ofFloat(view, "scaleY", 0.1f, 1f) };
47 | // ....
48 | case 3:
49 | return new Animator[] {ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0) };
50 | case 4:
51 | return new Animator[] {ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0) };
52 |
53 | }
54 | return null;
55 | }
56 |
57 |
58 | public void setAnimator(PropertyValuesHolder[] animators) {
59 | this.animators = animators;
60 | }
61 |
62 | public void setAnimatorFlag(int flag) {
63 | this.flag = flag;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/demotest/testapp/MarshonRecyclerViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.demotest.testapp;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.View;
9 |
10 | import com.demotest.testapp.adapter.MarshonRecyclerAdapter;
11 | import com.marshon.mrecyclerview.MRecyclerView;
12 | import com.marshon.swipe.SwipeWraper;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 |
18 |
19 | /**
20 | * Created by Administrator on 2016/4/25.
21 | */
22 | public class MarshonRecyclerViewActivity extends AppCompatActivity {
23 | private ChooseAnimatorsAdapter animAdapter;
24 | private List datas;
25 | private MRecyclerView mRecyclerView;
26 |
27 | @Override
28 | protected void onCreate(@Nullable Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_marsreview);
31 | mRecyclerView = (MRecyclerView) findViewById(R.id.mRecyclerView);
32 | mRecyclerView.setPullRefreshEnabled(true);
33 | mRecyclerView.setLoadingMoreEnabled(true);
34 | mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
35 |
36 | //1.make full data test
37 | datas = makeDatas();
38 | MarshonRecyclerAdapter adapter= new MarshonRecyclerAdapter(this,R.layout.listitem, datas) {
39 | @Override
40 | public void convert(final RecyclerView.ViewHolder holder, final int position) {
41 | View deleteView = holder.itemView.findViewById(R.id.tv_delete);
42 | final SwipeWraper swipelayout = (SwipeWraper) holder.itemView.findViewById(R.id.swipelayout);
43 | deleteView.setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | swipelayout.close(true);
47 | datas.remove(holder.getLayoutPosition()-1);
48 | animAdapter.notifyItemRemoved(holder.getLayoutPosition());
49 | }
50 | });
51 | }
52 | };
53 |
54 | //2.set up recyclerview
55 | final LinearLayoutManager manager=new LinearLayoutManager(this);
56 | //3.给adapter装饰上animAdapter
57 | animAdapter =new ChooseAnimatorsAdapter(adapter);
58 | animAdapter.setAnimatorFlag(ChooseAnimatorsAdapter.ANIMATORFLAG_SCALE);
59 | mRecyclerView.setAdapter(animAdapter);
60 | mRecyclerView.setLayoutManager(manager);
61 | mRecyclerView.setLoadingListener(new MRecyclerView.LoadingListener() {
62 | @Override
63 | public void onRefresh() {
64 |
65 | }
66 |
67 | @Override
68 | public void onLoadMore() {
69 | mRecyclerView.postDelayed(new Runnable() {
70 | @Override
71 | public void run() {
72 | for(int i=0;i<15;i++){
73 | datas.add("");
74 | }
75 | animAdapter.notifyDataSetChanged();
76 | }
77 | },3000);
78 | }
79 | });
80 | }
81 |
82 |
83 | protected List makeDatas() {
84 | List datas = new ArrayList();
85 | for(int i=0;i<400;i++){
86 | datas.add(""+i);
87 | }
88 | return datas;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/demotest/testapp/adapter/MarshonRecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.demotest.testapp.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Created by Marshon.Chen on 2016/7/26.
12 | * DESC:
13 | */
14 | public abstract class MarshonRecyclerAdapter extends RecyclerView.Adapter {
15 |
16 | private int listitem;
17 | private List mDatas;
18 | private Context mContext;
19 |
20 | public MarshonRecyclerAdapter(Context context, int listitem, List mDatas){
21 | this.mContext=context;
22 | this.mDatas=mDatas;
23 | this.listitem=listitem;
24 | }
25 | @Override
26 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
27 |
28 | View itemView=View.inflate(mContext, listitem,null);
29 | return new MViewHolder(itemView);
30 | }
31 |
32 | @Override
33 | public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
34 | convert(holder,position);
35 | }
36 |
37 | public abstract void convert(RecyclerView.ViewHolder holder, final int position);
38 |
39 | @Override
40 | public int getItemCount() {
41 | return mDatas.size();
42 | }
43 |
44 |
45 | class MViewHolder extends RecyclerView.ViewHolder{
46 |
47 | public MViewHolder(View itemView) {
48 | super(itemView);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/beauty.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/sample/src/main/res/drawable/beauty.jpg
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/sample/src/main/res/drawable/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable/meinv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenchengyin/MRecyclerView/94a913223534b877428a9b7bfd2740686e1a9a79/sample/src/main/res/drawable/meinv.png
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_marsreview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
17 |
18 |
19 |
20 |
23 |
27 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/listitem.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
25 |
26 |
27 |
28 |
29 |
30 |
35 |
36 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Marshon
4 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample'
2 | include ':mrecyclerview'
3 |
--------------------------------------------------------------------------------