├── !_apk └── sample.apk ├── !_img ├── img1.png ├── img1_small.png ├── img2.png └── img3.png ├── .gitignore ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── rvdatabinding ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── drextended │ │ └── rvdatabinding │ │ ├── Converters.java │ │ ├── ListConfig.java │ │ ├── adapter │ │ ├── BaseBindableAdapter.java │ │ ├── BindableAdapter.java │ │ ├── BindingHolder.java │ │ ├── ColorDividerItemDecoration.java │ │ ├── DividerItemDecoration.java │ │ ├── LoadMoreScrollListener.java │ │ └── TwoWayLoadingScrollListener.java │ │ └── delegate │ │ ├── ActionAdapterDelegate.java │ │ ├── BaseBindingAdapterDelegate.java │ │ ├── BaseListBindingAdapterDelegate.java │ │ ├── IdHolder.java │ │ ├── ModelActionItemDelegate.java │ │ └── ModelItemDelegate.java │ └── res │ ├── layout │ └── item_fallback.xml │ └── values │ ├── dimens.xml │ └── strings.xml ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── drextended │ │ └── rvdbsample │ │ ├── model │ │ ├── ActionType.java │ │ ├── Advertisement.java │ │ ├── BaseModel.java │ │ ├── Location.java │ │ └── User.java │ │ ├── util │ │ ├── CircleBorderedTransform.java │ │ ├── Converters.java │ │ ├── DummyDataProvider.java │ │ └── SimpleCallback.java │ │ ├── view │ │ ├── MainActivity.java │ │ └── PageFragment.java │ │ └── viewmodel │ │ ├── AllInOneListViewModel.java │ │ ├── ListViewModel.java │ │ ├── LocationListViewModel.java │ │ ├── UserListViewModel.java │ │ ├── action │ │ ├── OpenLocationAction.java │ │ └── ShowToastAction.java │ │ └── delegate │ │ ├── AdvertisementDelegate.java │ │ ├── LocationDelegate.java │ │ └── UserDelegate.java │ └── res │ ├── anim │ ├── scale_in.xml │ └── slide_in_top.xml │ ├── animator │ └── raise.xml │ ├── layout │ ├── activity_main.xml │ ├── fragment_page.xml │ ├── item_advertisment.xml │ ├── item_location.xml │ └── item_user.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── settings.gradle /!_apk/sample.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/!_apk/sample.apk -------------------------------------------------------------------------------- /!_img/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/!_img/img1.png -------------------------------------------------------------------------------- /!_img/img1_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/!_img/img1_small.png -------------------------------------------------------------------------------- /!_img/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/!_img/img2.png -------------------------------------------------------------------------------- /!_img/img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/!_img/img3.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DataBinding for RecyclerView 2 | 3 | [ ![Download](https://api.bintray.com/packages/drstranges/android-extended/databinding-for-recyclerview/images/download.svg) ](https://bintray.com/drstranges/android-extended/databinding-for-recyclerview/_latestVersion) 4 | 5 | ## Overview 6 | 7 | This library provides simple and flexible way to configuration RecyclerView using android data binding. 8 | 9 | Add library as gradle dependency 10 | 11 | ```gradle 12 | repositories { 13 | jcenter() 14 | } 15 | dependencies { 16 | compile 'com.drextended.rvdatabinding:rvdatabinding:1.1.0' 17 | } 18 | 19 | // Don't forget to enable data binding 20 | dataBinding { 21 | enabled = true 22 | } 23 | ``` 24 | 25 | ## Features 26 | - `.ListConfig` - Simple builder for configuration RecyclerView. 27 | - `.BindableAdapter` - Simple Recycler View Adapter for using with data-binding. 28 | - `.BindingHolder` - Simple View Holder for using with data-binding. 29 | - `.DividerItemDecoration` - Simple divider decoration for RecyclerView. 30 | - `.ColorDividerItemDecoration` - Simple colored divider decoration for RecyclerView. 31 | - `.LoadMoreScrollListener` - Simple RecyclerView ScrollListener for implementing lazy loading list (endless list). 32 | - `.TwoWayLoadingScrollListener` - Simple RecyclerView ScrollListener for implementing two-way lazy loading list (endless list). 33 | - `.BaseBindingAdapterDelegate` - Base RecyclerView item delegate for using with data-binding. 34 | - `.ModelItemDelegate` - Generic ActionDelegate. You can use this one if you do not want to implement custom one. 35 | 36 | ## Usage 37 | 38 | ###1. At first you definitely should have pojo-models for items 39 | 40 | ```java 41 | public class User implements BaseModel { 42 | public String name; 43 | public String avatar; 44 | } 45 | public class Location implements BaseModel { 46 | public String name; 47 | public String image; 48 | } 49 | public class Advertisement implements BaseModel { 50 | public String label; 51 | public String image; 52 | } 53 | ``` 54 | 55 | ###2. Then you should create layouts for each item and for your list page 56 | 57 | **fragment_page.xml** 58 | ```xml 59 | 60 | 61 | 64 | 65 | 66 | 70 | 71 | 72 | ``` 73 | 74 | **item_user.xml** 75 | ```xml 76 | 77 | 78 | 79 | 80 | 83 | 84 | 87 | 88 | 89 | 95 | 96 | 97 | 98 | 106 | 107 | 110 | 111 | 112 | 113 | 114 | ``` 115 | The same for **item_location.xml** and for **item_advertisement.xml** 116 | 117 | ###3. Then create ItemDelegates for items if you do not want to use generic 118 | 119 | **UserDelegate.java** 120 | ```java 121 | public class UserDelegate extends ActionAdapterDelegate { 122 | 123 | public UserDelegate(final ActionClickListener actionHandler) { 124 | super(actionHandler); 125 | } 126 | 127 | @Override 128 | public boolean isForViewType(@NonNull final List items, final int position) { 129 | return items.get(position) instanceof User; 130 | } 131 | 132 | @NonNull 133 | @Override 134 | public BindingHolder onCreateViewHolder(final ViewGroup parent) { 135 | return BindingHolder.newInstance(R.layout.item_user, LayoutInflater.from(parent.getContext()), parent, false); 136 | } 137 | 138 | @Override 139 | public void onBindViewHolder(@NonNull final List items, final int position, @NonNull final BindingHolder holder) { 140 | final User user = (User) items.get(position); 141 | holder.getBinding().setUser(user); 142 | holder.getBinding().setActionHandler(getActionHandler()); 143 | } 144 | 145 | @Override 146 | public long getItemId(final List items, final int position) { 147 | return items.get(position).getId(); 148 | } 149 | } 150 | ``` 151 | 152 | ###4. Assemble all this in your viewmodel 153 | 154 | **AllInOneListViewModel.java** 155 | ```java 156 | // Used action-handler library for handling click/long click in items: https://github.com/drstranges/ActionHandler 157 | final ActionClickListener actionHandler = new ActionHandler.Builder() 158 | //.addAction(null, new SimpleAnimationAction()) // Applied for any actionType 159 | //.addAction(null, new TrackAction()) // Applied for any actionType 160 | .addAction(ActionType.OPEN, new OpenProfileAction()) 161 | .addAction(ActionType.MENU, new CompositeAction( 162 | (context, model) -> getTitle(model), 163 | new ActionItem(ActionType.MENU_ITEM_1, new OpenSecondActivity(), R.string.menu_item_1), 164 | new ActionItem(ActionType.MENU_ITEM_2, new ShowToastAction(), R.string.menu_item_2) 165 | )) 166 | .setActionInterceptor(this) 167 | .setActionFiredListener(this) 168 | .build(); 169 | 170 | // Build generic bindable adapter. Just list all used item delegates 171 | mAdapter = new BindableAdapter<>( 172 | new UserDelegate(actionHandler), // you can create custom delegate 173 | //new ModelActionItemDelegate(actionHandler, User.class, R.layout.item_user, BR.user), // or use generic 174 | new ModelActionItemDelegate(actionHandler, Location.class, R.layout.item_location, BR.location), 175 | new ModelActionItemDelegate(actionHandler, Advertisement.class, R.layout.item_advertisment, BR.advertisment) 176 | ); 177 | 178 | // Config for RecyclerView 179 | mListConfig = new ListConfig.Builder(mAdapter) 180 | .setLayoutManagerProvider(new SimpleGridLayoutManagerProvider(mSpanCount, getSpanSizeLookup())) // if not set, LinearLayoutManager applied by default 181 | .addItemDecoration(new ColorDividerItemDecoration(color, spacing, SPACE_LEFT|SPACE_TOP, false)) 182 | //.setDefaultDividerEnabled(true) 183 | .addOnScrollListener(new OnLoadMoreScrollListener(mCallback)) 184 | .setItemAnimator(getCustomItemAnimator()) 185 | // .setHasFixedSize(true) 186 | .setItemTouchHelper(getItemTouchHelper()) 187 | .build(context); 188 | 189 | loadData(); 190 | ``` 191 | 192 | ## Used Library: 193 | - [AdapterDelegates](https://github.com/sockeqwe/AdapterDelegates) 194 | - [ActionHandler](https://github.com/drstranges/ActionHandler) 195 | 196 | 197 | ## Inspired by: 198 | 199 | https://github.com/sockeqwe/AdapterDelegates 200 | 201 | http://hannesdorfmann.com/android/adapter-delegates 202 | 203 | ## Sample 204 | 205 | [Sample apk file](./!_apk/sample.apk) 206 | 207 | 208 | 209 | License 210 | ======= 211 | 212 | Copyright 2016 Roman Donchenko 213 | 214 | Licensed under the Apache License, Version 2.0 (the "License"); 215 | you may not use this file except in compliance with the License. 216 | You may obtain a copy of the License at 217 | 218 | http://www.apache.org/licenses/LICENSE-2.0 219 | 220 | Unless required by applicable law or agreed to in writing, software 221 | distributed under the License is distributed on an "AS IS" BASIS, 222 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 223 | See the License for the specific language governing permissions and 224 | limitations under the License. 225 | -------------------------------------------------------------------------------- /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.1.3' 9 | 10 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1' 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /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 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 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 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /rvdatabinding/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /rvdatabinding/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | ext { 4 | libraryVersionRevision = 0 5 | libraryVersionMinor = 1 6 | libraryVersionMajor = 1 7 | 8 | libraryVersion = libraryVersionMajor + '.' + libraryVersionMinor + '.' + libraryVersionRevision 9 | 10 | bintrayRepo = 'android-extended' 11 | bintrayName = 'databinding-for-recyclerview' 12 | 13 | publishedGroupId = 'com.drextended.rvdatabinding' 14 | libraryName = 'DataBinding For RecyclerView' 15 | artifact = 'rvdatabinding' 16 | 17 | libraryDescription = 'Provides flexible way to use data binding with RecyclerView!' 18 | 19 | siteUrl = 'https://github.com/drstranges/DataBinding_For_RecyclerView' 20 | gitUrl = 'https://github.com/drstranges/DataBinding_For_RecyclerView.git' 21 | 22 | developerId = 'drstranges' 23 | developerName = 'Roman Donchenko' 24 | developerEmail = 'drstranges@gmail.com' 25 | 26 | licenseName = 'The Apache Software License, Version 2.0' 27 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 28 | allLicenses = ["Apache-2.0"] 29 | } 30 | 31 | android { 32 | compileSdkVersion 24 33 | buildToolsVersion "24.0.2" 34 | 35 | dataBinding { 36 | enabled = true 37 | } 38 | 39 | defaultConfig { 40 | minSdkVersion 15 41 | targetSdkVersion 24 42 | versionCode libraryVersionRevision 43 | versionName libraryVersion 44 | } 45 | buildTypes { 46 | release { 47 | minifyEnabled false 48 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 49 | } 50 | } 51 | } 52 | 53 | dependencies { 54 | compile fileTree(dir: 'libs', include: ['*.jar']) 55 | 56 | compile 'com.hannesdorfmann:adapterdelegates2:2.0.1' 57 | compile 'com.drextended.actionhandler:actionhandler:0.1.16' 58 | 59 | provided 'com.android.support:appcompat-v7:+' 60 | provided 'com.android.support:recyclerview-v7:+' 61 | } 62 | 63 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle' 64 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle' 65 | 66 | apply plugin: 'com.jfrog.bintray' 67 | apply plugin: 'com.github.dcendents.android-maven' 68 | 69 | version = libraryVersion 70 | 71 | task sourcesJar(type: Jar) { 72 | classifier = 'sources' 73 | from android.sourceSets.main.java.srcDirs 74 | } 75 | 76 | task javadoc(type: Javadoc) { 77 | source = android.sourceSets.main.java.srcDirs 78 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 79 | failOnError = false 80 | } 81 | 82 | 83 | task javadocJar(type: Jar, dependsOn: javadoc) { 84 | classifier = 'javadoc' 85 | from javadoc.destinationDir 86 | } 87 | 88 | artifacts { 89 | archives javadocJar 90 | archives sourcesJar 91 | } 92 | 93 | // Bintray 94 | Properties properties = new Properties() 95 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 96 | 97 | bintray { 98 | user = properties.getProperty("bintray.user") 99 | key = properties.getProperty("bintray.apikey") 100 | 101 | configurations = ['archives'] 102 | pkg { 103 | repo = bintrayRepo 104 | name = bintrayName 105 | desc = libraryDescription 106 | websiteUrl = siteUrl 107 | vcsUrl = gitUrl 108 | licenses = allLicenses 109 | publish = true 110 | publicDownloadNumbers = true 111 | version { 112 | desc = libraryDescription 113 | gpg { 114 | sign = true //Determines whether to GPG sign the files. The default is false 115 | passphrase = properties.getProperty("bintray.gpg.password") 116 | //Optional. The passphrase for GPG signing' 117 | } 118 | } 119 | } 120 | } 121 | 122 | group = publishedGroupId // Maven Group ID for the artifact 123 | 124 | install { 125 | repositories.mavenInstaller { 126 | // This generates POM.xml with proper parameters 127 | pom { 128 | project { 129 | packaging 'aar' 130 | groupId publishedGroupId 131 | artifactId artifact 132 | 133 | // Add your description here 134 | name libraryName 135 | description libraryDescription 136 | url siteUrl 137 | 138 | // Set your license 139 | licenses { 140 | license { 141 | name licenseName 142 | url licenseUrl 143 | } 144 | } 145 | developers { 146 | developer { 147 | id developerId 148 | name developerName 149 | email developerEmail 150 | } 151 | } 152 | scm { 153 | connection gitUrl 154 | developerConnection gitUrl 155 | url siteUrl 156 | 157 | } 158 | } 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /rvdatabinding/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:\Android_Env\android-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 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/Converters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding; 18 | 19 | import android.databinding.BindingAdapter; 20 | import android.support.v7.widget.RecyclerView; 21 | 22 | /** 23 | * Helper class for collect all data binding adapters in one place 24 | */ 25 | public class Converters { 26 | 27 | /** 28 | * Binding adapter to apply RecyclerView config. 29 | * Sample: 30 | *
31 |      * {@code
32 |      *     <android.support.v7.widget.RecyclerView
33 |      *     android:layout_width="match_parent"
34 |      *     android:layout_height="match_parent"
35 |      *     app:listConfig="@{viewModel.listConfig}"
36 |      *     />
37 |      * }
38 |      * 
39 | * 40 | * @param recyclerView The RecyclerView to apply config 41 | * @param config The config for RecyclerView 42 | */ 43 | @BindingAdapter({"listConfig"}) 44 | public static void configRecyclerView(RecyclerView recyclerView, ListConfig config) { 45 | if (config == null) return; 46 | config.applyConfig(recyclerView.getContext(), recyclerView); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/ListConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding; 18 | 19 | import android.content.Context; 20 | import android.support.annotation.IntRange; 21 | import android.support.v7.widget.GridLayoutManager; 22 | import android.support.v7.widget.LinearLayoutManager; 23 | import android.support.v7.widget.RecyclerView; 24 | import android.support.v7.widget.RecyclerView.LayoutManager; 25 | import android.support.v7.widget.StaggeredGridLayoutManager; 26 | import android.support.v7.widget.helper.ItemTouchHelper; 27 | 28 | import com.drextended.rvdatabinding.adapter.ColorDividerItemDecoration; 29 | import com.drextended.rvdatabinding.adapter.DividerItemDecoration; 30 | 31 | import java.util.ArrayList; 32 | import java.util.Collections; 33 | import java.util.List; 34 | 35 | /** 36 | * Helper class for simple configuring of RecyclerView 37 | */ 38 | public class ListConfig { 39 | private final RecyclerView.Adapter mAdapter; 40 | private final LayoutManagerProvider mLayoutManagerProvider; 41 | private final RecyclerView.ItemAnimator mItemAnimator; 42 | private final List mItemDecorations; 43 | private final List mScrollListeners; 44 | private final ItemTouchHelper mItemTouchHelper; 45 | private final boolean mHasFixedSize; 46 | 47 | private ListConfig(final RecyclerView.Adapter adapter, 48 | final LayoutManagerProvider layoutManagerProvider, 49 | final RecyclerView.ItemAnimator itemAnimator, final List itemDecorations, 50 | final List scrollListeners, 51 | final ItemTouchHelper itemTouchHelper, 52 | final boolean hasFixedSize) { 53 | mAdapter = adapter; 54 | mLayoutManagerProvider = layoutManagerProvider; 55 | mItemAnimator = itemAnimator; 56 | mItemDecorations = itemDecorations != null ? itemDecorations : Collections.emptyList(); 57 | mScrollListeners = scrollListeners != null ? scrollListeners : Collections.emptyList(); 58 | mItemTouchHelper = itemTouchHelper; 59 | mHasFixedSize = hasFixedSize; 60 | } 61 | 62 | /** 63 | * Applies defined configuration for RecyclerView 64 | * 65 | * @param context the context 66 | * @param recyclerView the target recycler view for applying the configuration 67 | */ 68 | public void applyConfig(final Context context, final RecyclerView recyclerView) { 69 | final LayoutManager layoutManager; 70 | if (mAdapter == null || mLayoutManagerProvider == null || (layoutManager = mLayoutManagerProvider.get(context)) == null) 71 | return; 72 | recyclerView.setLayoutManager(layoutManager); 73 | recyclerView.setHasFixedSize(mHasFixedSize); 74 | recyclerView.setAdapter(mAdapter); 75 | for (RecyclerView.ItemDecoration itemDecoration : mItemDecorations) { 76 | recyclerView.addItemDecoration(itemDecoration); 77 | } 78 | for (RecyclerView.OnScrollListener scrollListener : mScrollListeners) { 79 | recyclerView.addOnScrollListener(scrollListener); 80 | } 81 | if (mItemAnimator != null) { 82 | recyclerView.setItemAnimator(mItemAnimator); 83 | } 84 | if (mItemTouchHelper != null) { 85 | mItemTouchHelper.attachToRecyclerView(recyclerView); 86 | } 87 | } 88 | 89 | /** 90 | * Builder for setting ListConfig 91 | * Sample: 92 | *
 93 |      * {@code
 94 |      *      ListConfig listConfig = new ListConfig.Builder(mAdapter)
 95 |      *          .setLayoutManagerProvider(new SimpleGridLayoutManagerProvider(mSpanCount, getSpanSizeLookup()))
 96 |      *          .addItemDecoration(new ColorDividerItemDecoration(color, spacing, SPACE_LEFT|SPACE_TOP, false))
 97 |      *          .setDefaultDividerEnabled(true)
 98 |      *          .addOnScrollListener(new OnLoadMoreScrollListener(mCallback))
 99 |      *          .setItemAnimator(getItemAnimator())
100 |      *          .setHasFixedSize(true)
101 |      *          .setItemTouchHelper(getItemTouchHelper())
102 |      *          .build(context);
103 |      * }
104 |      * 
105 | * If LinearLayoutManager will be used by default 106 | */ 107 | public static class Builder { 108 | private final RecyclerView.Adapter mAdapter; 109 | private LayoutManagerProvider mLayoutManagerProvider; 110 | private RecyclerView.ItemAnimator mItemAnimator; 111 | private List mItemDecorations; 112 | private List mOnScrollListeners; 113 | private ItemTouchHelper mItemTouchHelper; 114 | private boolean mHasFixedSize; 115 | private int mDefaultDividerSize = -1; 116 | 117 | /** 118 | * Creates new Builder for config RecyclerView with the adapter 119 | * 120 | * @param adapter the adapter, which will be set to the RecyclerView 121 | */ 122 | public Builder(RecyclerView.Adapter adapter) { 123 | mAdapter = adapter; 124 | } 125 | 126 | /** 127 | * Set Layout manager provider. If not set default {@link LinearLayoutManager} will be applied 128 | * 129 | * @param layoutManagerProvider the layout manager provider. Can be custom or one of 130 | * simple: {@link SimpleLinearLayoutManagerProvider}, 131 | * {@link SimpleGridLayoutManagerProvider} or 132 | * {@link SimpleStaggeredGridLayoutManagerProvider}. 133 | * @return the builder 134 | */ 135 | public Builder setLayoutManagerProvider(LayoutManagerProvider layoutManagerProvider) { 136 | mLayoutManagerProvider = layoutManagerProvider; 137 | return this; 138 | } 139 | 140 | /** 141 | * Set {@link android.support.v7.widget.RecyclerView.ItemAnimator} 142 | * 143 | * @param itemAnimator the item animator 144 | * @return the builder 145 | */ 146 | public Builder setItemAnimator(RecyclerView.ItemAnimator itemAnimator) { 147 | mItemAnimator = itemAnimator; 148 | return this; 149 | } 150 | 151 | /** 152 | * Set {@link android.support.v7.widget.RecyclerView.ItemDecoration} 153 | * 154 | * @param itemDecoration the item decoration. Can be set any custom item decoration 155 | * or used one of simple: {@link DividerItemDecoration} or 156 | * {@link ColorDividerItemDecoration} 157 | * @return the builder 158 | */ 159 | public Builder addItemDecoration(RecyclerView.ItemDecoration itemDecoration) { 160 | if (mItemDecorations == null) { 161 | mItemDecorations = new ArrayList<>(); 162 | } 163 | mItemDecorations.add(itemDecoration); 164 | return this; 165 | } 166 | 167 | /** 168 | * Set {@link android.support.v7.widget.RecyclerView.OnScrollListener} 169 | * 170 | * @param onScrollListener the scroll listener. Can be set any custom or used one of 171 | * simple: {@link com.drextended.rvdatabinding.adapter.LoadMoreScrollListener} 172 | * or {@link com.drextended.rvdatabinding.adapter.TwoWayLoadingScrollListener} 173 | * @return the builder 174 | */ 175 | public Builder addOnScrollListener(RecyclerView.OnScrollListener onScrollListener) { 176 | if (mOnScrollListeners == null) { 177 | mOnScrollListeners = new ArrayList<>(); 178 | } 179 | mOnScrollListeners.add(onScrollListener); 180 | return this; 181 | } 182 | 183 | /** 184 | * Set true if adapter changes cannot affect the size of the RecyclerView. 185 | * Applied to {@link RecyclerView#setHasFixedSize(boolean)} 186 | * 187 | * @param isFixedSize true if RecyclerView items have fixed size 188 | * @return the builder 189 | */ 190 | public Builder setHasFixedSize(boolean isFixedSize) { 191 | mHasFixedSize = isFixedSize; 192 | return this; 193 | } 194 | 195 | /** 196 | * Set true to apply default divider with default size of 4dp. 197 | * 198 | * @param isEnabled set true to apply default divider. 199 | * @return the builder 200 | */ 201 | public Builder setDefaultDividerEnabled(boolean isEnabled) { 202 | mDefaultDividerSize = isEnabled ? 0 : -1; 203 | return this; 204 | } 205 | 206 | /** 207 | * Enables defoult divider with custom size 208 | * 209 | * @param size 210 | * @return the builder 211 | */ 212 | public Builder setDefaultDividerSize(int size) { 213 | mDefaultDividerSize = size; 214 | return this; 215 | } 216 | 217 | /** 218 | * Set {@link ItemTouchHelper} 219 | * 220 | * @param itemTouchHelper the ItemTouchHelper to apply for RecyclerView 221 | * @return the builder 222 | */ 223 | public Builder setItemTouchHelper(ItemTouchHelper itemTouchHelper) { 224 | mItemTouchHelper = itemTouchHelper; 225 | return this; 226 | } 227 | 228 | /** 229 | * Creates new {@link ListConfig} with defined configuration 230 | * If LayoutManagerProvider is not set, the {@link SimpleLinearLayoutManagerProvider} 231 | * will be used. 232 | * 233 | * @param context the context 234 | * @return the new ListConfig 235 | */ 236 | public ListConfig build(Context context) { 237 | if (mLayoutManagerProvider == null) 238 | mLayoutManagerProvider = new SimpleLinearLayoutManagerProvider(); 239 | if (mDefaultDividerSize >= 0) { 240 | if (mDefaultDividerSize == 0) mDefaultDividerSize = context.getResources() 241 | .getDimensionPixelSize(R.dimen.rvdb_list_divider_size_default); 242 | addItemDecoration(new DividerItemDecoration(mDefaultDividerSize)); 243 | } 244 | 245 | return new ListConfig( 246 | mAdapter, 247 | mLayoutManagerProvider, 248 | mItemAnimator, mItemDecorations, 249 | mOnScrollListeners, 250 | mItemTouchHelper, 251 | mHasFixedSize); 252 | } 253 | } 254 | 255 | /** 256 | * The provider of LayoutManager for RecyclerView 257 | */ 258 | public interface LayoutManagerProvider { 259 | LayoutManager get(Context context); 260 | } 261 | 262 | /** 263 | * The simple LayoutManager provider for {@link LinearLayoutManager} 264 | */ 265 | public static class SimpleLinearLayoutManagerProvider implements LayoutManagerProvider { 266 | @Override 267 | public LayoutManager get(Context context) { 268 | return new LinearLayoutManager(context); 269 | } 270 | } 271 | 272 | /** 273 | * The simple LayoutManager provider for {@link GridLayoutManager} 274 | */ 275 | public static class SimpleGridLayoutManagerProvider implements LayoutManagerProvider { 276 | private final int mSpanCount; 277 | private GridLayoutManager.SpanSizeLookup mSpanSizeLookup; 278 | 279 | public SimpleGridLayoutManagerProvider(@IntRange(from = 1) int mSpanCount) { 280 | this.mSpanCount = mSpanCount; 281 | } 282 | 283 | public SimpleGridLayoutManagerProvider(int spanCount, GridLayoutManager.SpanSizeLookup spanSizeLookup) { 284 | mSpanCount = spanCount; 285 | mSpanSizeLookup = spanSizeLookup; 286 | } 287 | 288 | @Override 289 | public LayoutManager get(Context context) { 290 | GridLayoutManager layoutManager = new GridLayoutManager(context, mSpanCount); 291 | if (mSpanSizeLookup != null) layoutManager.setSpanSizeLookup(mSpanSizeLookup); 292 | return layoutManager; 293 | } 294 | } 295 | 296 | /** 297 | * The simple LayoutManager provider for {@link StaggeredGridLayoutManager} 298 | */ 299 | public static class SimpleStaggeredGridLayoutManagerProvider implements LayoutManagerProvider { 300 | private final int mSpanCount; 301 | private final int mOrientation; 302 | 303 | public SimpleStaggeredGridLayoutManagerProvider(@IntRange(from = 1) int spanCount) { 304 | this(spanCount, StaggeredGridLayoutManager.VERTICAL); 305 | } 306 | 307 | public SimpleStaggeredGridLayoutManagerProvider(@IntRange(from = 1) int spanCount, final int orientation) { 308 | this.mSpanCount = spanCount; 309 | this.mOrientation = orientation; 310 | } 311 | 312 | @Override 313 | public LayoutManager get(Context context) { 314 | return new StaggeredGridLayoutManager(mSpanCount, mOrientation); 315 | } 316 | } 317 | } -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/BaseBindableAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.v7.widget.RecyclerView; 21 | 22 | import com.drextended.rvdatabinding.delegate.IdHolder; 23 | import com.hannesdorfmann.adapterdelegates2.AbsDelegationAdapter; 24 | import com.hannesdorfmann.adapterdelegates2.AdapterDelegate; 25 | import com.hannesdorfmann.adapterdelegates2.AdapterDelegatesManager; 26 | 27 | /** 28 | * RecyclerView Adapter for using with data binding. Dataset can be any type, not only List of items. 29 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 30 | * 31 | * @param The type of the datasoure / items 32 | */ 33 | public abstract class BaseBindableAdapter extends AbsDelegationAdapter { 34 | 35 | /** 36 | * Creates Adapter with empty adapter delegates manager 37 | */ 38 | public BaseBindableAdapter() { 39 | } 40 | 41 | public BaseBindableAdapter(@NonNull AdapterDelegatesManager delegatesManager) { 42 | super(delegatesManager); 43 | } 44 | 45 | public BaseBindableAdapter(AdapterDelegate... delegates) { 46 | super(new AdapterDelegatesManager()); 47 | for (AdapterDelegate delegate : delegates) delegatesManager.addDelegate(delegate); 48 | } 49 | 50 | public BaseBindableAdapter(T items, AdapterDelegatesManager delegatesManager) { 51 | super(delegatesManager); 52 | setItems(items); 53 | } 54 | 55 | public BaseBindableAdapter(T items, AdapterDelegate... delegates) { 56 | this(delegates); 57 | setItems(items); 58 | } 59 | 60 | /** 61 | * Get item id if specific AdapterDelegate implement IdHolder interface 62 | * 63 | * @param position position of item in data source 64 | * @return the item id 65 | */ 66 | @Override 67 | public long getItemId(int position) { 68 | final int viewType = delegatesManager.getItemViewType(items, position); 69 | final AdapterDelegate delegate = delegatesManager.getDelegateForViewType(viewType); 70 | //noinspection unchecked 71 | return delegate instanceof IdHolder ? ((IdHolder) delegate).getItemId(items, position) : RecyclerView.NO_ID; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/BindableAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import com.hannesdorfmann.adapterdelegates2.AdapterDelegate; 22 | import com.hannesdorfmann.adapterdelegates2.AdapterDelegatesManager; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * RecyclerView Adapter for using with data binding. Uses List of items as dataset. 28 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 29 | * 30 | * @param The type of the datasoure / items 31 | */ 32 | 33 | public class BindableAdapter extends BaseBindableAdapter { 34 | 35 | public BindableAdapter() { 36 | } 37 | 38 | public BindableAdapter(@NonNull final AdapterDelegatesManager delegatesManager) { 39 | super(delegatesManager); 40 | } 41 | 42 | public BindableAdapter(AdapterDelegate... adapterDelegates) { 43 | super(adapterDelegates); 44 | } 45 | 46 | public BindableAdapter(final T items, final AdapterDelegatesManager delegatesManager) { 47 | super(items, delegatesManager); 48 | } 49 | 50 | public BindableAdapter(final T items, AdapterDelegate... adapterDelegates) { 51 | super(items, adapterDelegates); 52 | } 53 | 54 | @Override 55 | public int getItemCount() { 56 | return items != null ? items.size() : 0; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/BindingHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.databinding.DataBindingUtil; 20 | import android.databinding.ViewDataBinding; 21 | import android.support.annotation.LayoutRes; 22 | import android.support.annotation.Nullable; 23 | import android.support.v7.widget.RecyclerView; 24 | import android.view.LayoutInflater; 25 | import android.view.ViewGroup; 26 | 27 | /** 28 | * Recycler View Holder to use with data mBinding 29 | * 30 | * @param The type of view data binding 31 | */ 32 | public class BindingHolder extends RecyclerView.ViewHolder { 33 | 34 | /** 35 | * View data binding of this holder 36 | */ 37 | private VB mBinding; 38 | 39 | /** 40 | * Creates new View Holder from provided layout 41 | * 42 | * @param layoutId The layout resource ID of the layout to inflate. 43 | * @param inflater The LayoutInflater used to inflate the binding layout. 44 | * @param parent Optional view to be the parent of the generated hierarchy 45 | * @param attachToParent Whether the inflated hierarchy should be attached to the 46 | * parent parameter. If false, parent is only used to create 47 | * the correct subclass of LayoutParams for the root view in the XML. 48 | * @param The type of view data binding 49 | * @return The newly-created view-holder for the binding with inflated layout. 50 | */ 51 | public static BindingHolder newInstance( 52 | @LayoutRes int layoutId, LayoutInflater inflater, 53 | @Nullable ViewGroup parent, boolean attachToParent) { 54 | 55 | final VB vb = DataBindingUtil.inflate(inflater, layoutId, parent, attachToParent); 56 | return new BindingHolder<>(vb); 57 | } 58 | 59 | /** 60 | * Creates new View Holder from provided binding 61 | * 62 | * @param binding The view data binding class for this view-holder 63 | */ 64 | public BindingHolder(VB binding) { 65 | super(binding.getRoot()); 66 | mBinding = binding; 67 | } 68 | 69 | /** 70 | * Returns view data binding of this holder 71 | * 72 | * @return view data binding of this holder 73 | */ 74 | public VB getBinding() { 75 | return mBinding; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/ColorDividerItemDecoration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.graphics.Canvas; 20 | import android.graphics.Paint; 21 | import android.support.v7.widget.RecyclerView; 22 | import android.view.View; 23 | 24 | /** 25 | * ItemDecoration for colored spacing (divider) between items in RecyclerView 26 | */ 27 | public class ColorDividerItemDecoration extends DividerItemDecoration { 28 | 29 | private final Paint mPaint; 30 | 31 | /** 32 | * Creates ItemDecoration for colored spacing (divider) between items in RecyclerView 33 | * 34 | * @param color the color of spacing area 35 | * @param spacing the spacing size in pixels 36 | * @param spacingConfig the spacing config. Can be set as bit mask like {@code SPACE_LEFT|SPACE_TOP}. 37 | * Available values: 38 | * {@link DividerItemDecoration#SPACE_LEFT}, {@link DividerItemDecoration#SPACE_TOP}, 39 | * {@link DividerItemDecoration#SPACE_RIGHT}, {@link DividerItemDecoration#SPACE_BOTTOM}. 40 | * @param disableFirst true for not drawing divider for first item. 41 | * @param disableLast true for not drawing divider for last item. 42 | */ 43 | public ColorDividerItemDecoration(int color, int spacing, int spacingConfig, boolean disableFirst, boolean disableLast) { 44 | super(spacing, spacingConfig, disableFirst, disableLast); 45 | mPaint = new Paint(); 46 | mPaint.setColor(color); 47 | mPaint.setStyle(Paint.Style.FILL); 48 | } 49 | 50 | @Override 51 | public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 52 | int childCount = parent.getChildCount(); 53 | for (int i = 0; i < childCount; i++) { 54 | View child = parent.getChildAt(i); 55 | drawDivider(c, child, parent); 56 | } 57 | } 58 | 59 | private void drawDivider(Canvas c, View child, RecyclerView parent) { 60 | RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 61 | int left, top, right, bottom; 62 | 63 | if (mDrawLeft && needDrawIfFirst(child, parent, SPACE_TOP)) { 64 | top = child.getTop() - params.topMargin; 65 | bottom = child.getBottom() + params.bottomMargin; 66 | right = child.getLeft() - params.leftMargin; 67 | left = right - mSpacing; 68 | drawDivider(c, left, top, right, bottom); 69 | } 70 | if (mDrawTop && needDrawIfFirst(child, parent, SPACE_TOP)) { 71 | bottom = child.getTop() - params.topMargin; 72 | top = bottom - mSpacing; 73 | left = child.getLeft() - params.leftMargin - (mDrawLeft ? mSpacing : 0); 74 | right = child.getRight() + params.rightMargin + (mDrawRight ? mSpacing : 0); 75 | drawDivider(c, left, top, right, bottom); 76 | } 77 | if (mDrawRight && needDrawIfLast(child, parent, SPACE_BOTTOM)) { 78 | top = child.getTop() - params.topMargin; 79 | bottom = child.getBottom() + params.bottomMargin; 80 | left = child.getRight() + params.rightMargin; 81 | right = left + mSpacing; 82 | drawDivider(c, left, top, right, bottom); 83 | } 84 | if (mDrawBottom && needDrawIfLast(child, parent, SPACE_BOTTOM)) { 85 | top = child.getBottom() + params.bottomMargin; 86 | bottom = top + mSpacing; 87 | left = child.getLeft() - params.leftMargin - (mDrawLeft ? mSpacing : 0); 88 | right = child.getRight() + params.rightMargin + (mDrawRight ? mSpacing : 0); 89 | drawDivider(c, left, top, right, bottom); 90 | } 91 | 92 | } 93 | 94 | private void drawDivider(Canvas c, int left, int top, int right, int bottom) { 95 | c.drawRect(left, top, right, bottom, mPaint); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/DividerItemDecoration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.graphics.Rect; 20 | import android.support.v7.widget.RecyclerView; 21 | import android.view.View; 22 | 23 | /** 24 | * ItemDecoration for spacing (divider) between items in RecyclerView 25 | */ 26 | public class DividerItemDecoration extends RecyclerView.ItemDecoration { 27 | 28 | public static final int SPACE_LEFT = 1; 29 | public static final int SPACE_RIGHT = 2; 30 | public static final int SPACE_TOP = 4; 31 | public static final int SPACE_BOTTOM = 8; 32 | // public static final int SPACE_GRID = 16; 33 | 34 | protected final int mSpacingConfig; 35 | protected final boolean mDrawLeft; 36 | protected final boolean mDrawTop; 37 | protected final boolean mDrawRight; 38 | protected final boolean mDrawBottom; 39 | private final boolean mDisableFirst; 40 | private final boolean mDisableLast; 41 | 42 | protected int mSpacing; 43 | 44 | /** 45 | * Creates ItemDecoration for colored spacing (divider) between items in RecyclerView 46 | * Make spacing on top of each item 47 | * 48 | * @param spacing the spacing size in pixels 49 | */ 50 | public DividerItemDecoration(final int spacing) { 51 | this(spacing, SPACE_TOP); 52 | } 53 | 54 | /** 55 | * Creates ItemDecoration for colored spacing (divider) between items in RecyclerView 56 | * 57 | * @param spacing the spacing size in pixels 58 | * @param spacingConfig the spacing config. Can be set as bit mask like {@code SPACE_LEFT|SPACE_TOP}. 59 | * Available values: 60 | * {@link DividerItemDecoration#SPACE_LEFT}, {@link DividerItemDecoration#SPACE_TOP}, 61 | * {@link DividerItemDecoration#SPACE_RIGHT}, {@link DividerItemDecoration#SPACE_BOTTOM}. 62 | */ 63 | public DividerItemDecoration(final int spacing, int spacingConfig) { 64 | this(spacing, spacingConfig, false, false); 65 | } 66 | 67 | /** 68 | * Creates ItemDecoration for colored spacing (divider) between items in RecyclerView 69 | * 70 | * @param spacing the spacing size in pixels 71 | * @param spacingConfig the spacing config. Can be set as bit mask like {@code SPACE_LEFT|SPACE_TOP}. 72 | * Available values: 73 | * {@link DividerItemDecoration#SPACE_LEFT}, {@link DividerItemDecoration#SPACE_TOP}, 74 | * {@link DividerItemDecoration#SPACE_RIGHT}, {@link DividerItemDecoration#SPACE_BOTTOM}. 75 | * @param disableFirst true for not drawing divider for first item. 76 | * @param disableLast true for not drawing divider for last item. 77 | */ 78 | public DividerItemDecoration(final int spacing, int spacingConfig, boolean disableFirst, boolean disableLast) { 79 | mSpacing = spacing; 80 | mSpacingConfig = spacingConfig; 81 | 82 | mDrawLeft = check(SPACE_LEFT); 83 | mDrawTop = check(SPACE_TOP); 84 | mDrawRight = check(SPACE_RIGHT); 85 | mDrawBottom = check(SPACE_BOTTOM); 86 | 87 | mDisableFirst = disableFirst; 88 | mDisableLast = disableLast; 89 | } 90 | 91 | @Override 92 | public void getItemOffsets(Rect outRect, View child, RecyclerView parent, RecyclerView.State state) { 93 | if (mDrawLeft && needDrawIfFirst(child, parent, SPACE_LEFT)) outRect.left = mSpacing; 94 | if (mDrawTop && needDrawIfFirst(child, parent, SPACE_TOP)) outRect.top = mSpacing; 95 | if (mDrawRight && needDrawIfLast(child, parent, SPACE_RIGHT)) outRect.right = mSpacing; 96 | if (mDrawBottom && needDrawIfLast(child, parent, SPACE_BOTTOM)) outRect.bottom = mSpacing; 97 | } 98 | 99 | protected boolean check(int value) { 100 | return (mSpacingConfig & value) == value; 101 | } 102 | 103 | protected boolean isFirstItem(View child, RecyclerView parent, final int spacingConfig) { 104 | return parent.getChildAdapterPosition(child) == 0; 105 | } 106 | 107 | protected boolean isLastItem(View child, RecyclerView parent) { 108 | final RecyclerView.Adapter adapter = parent.getAdapter(); 109 | return adapter != null && parent.getChildAdapterPosition(child) == adapter.getItemCount() - 1; 110 | } 111 | 112 | protected boolean needDrawIfFirst(View child, RecyclerView parent, final int spacingConfig) { 113 | return !(mDisableFirst && isFirstItem(child, parent, spacingConfig)); 114 | } 115 | 116 | protected boolean needDrawIfLast(View child, RecyclerView parent, final int spacingConfig) { 117 | return !(mDisableLast && isLastItem(child, parent)); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/LoadMoreScrollListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.v7.widget.LinearLayoutManager; 21 | import android.support.v7.widget.RecyclerView; 22 | import android.support.v7.widget.StaggeredGridLayoutManager; 23 | 24 | import static android.support.v7.widget.RecyclerView.LayoutManager; 25 | import static android.support.v7.widget.RecyclerView.OnScrollListener; 26 | 27 | /** 28 | * RecyclerView ScrollListener for implementing lazy loading list (endless list) 29 | *
 30 |  * {@code
 31 |  *      ListConfig listConfig = new ListConfig.Builder(mAdapter)
 32 |  *          .addOnScrollListener(new OnLoadMoreScrollListener(
 33 |  *              new OnLoadMoreListener {
 34 |  *                  public void onLoadMore() {
 35 |  *                      //Load new items
 36 |  *                  }
 37 |  *
 38 |  *                  public boolean isLoading() {
 39 |  *                      return isLoading; // true if loading in progress
 40 |  *                  }
 41 |  *              }
 42 |  *          ))
 43 |  *          .build(context);
 44 |  * }
 45 |  * 
46 | */ 47 | public class LoadMoreScrollListener extends OnScrollListener { 48 | 49 | private static final int DEFAULT_VISIBLE_THRESOLD = 5; 50 | private final OnLoadMoreListener mMoreListener; 51 | private int mVisibleThreshold; // The minimum amount of items to have below your current scroll position before loading more. 52 | private int firstVisibleItem, lastVisibleItem, visibleItemCount, totalItemCount; 53 | 54 | /** 55 | * Listener for implementing lazy loading list (endless list) 56 | */ 57 | public interface OnLoadMoreListener { 58 | /** 59 | * Callback for starting loading new portion of data 60 | */ 61 | void onLoadMore(); 62 | 63 | /** 64 | * Return loading status 65 | * 66 | * @return true if loading in progress 67 | */ 68 | boolean isLoading(); 69 | } 70 | 71 | /** 72 | * Creates ScrollListener for implementing lazy loading list (endless list) 73 | * If there are less then 5 items after last visible item in recycler view 74 | * and {@link OnLoadMoreListener#isLoading()} returns false, 75 | * then {@link OnLoadMoreListener#onLoadMore()} will be called. 76 | * 77 | * @param listener the callback {@link OnLoadMoreListener} 78 | */ 79 | public LoadMoreScrollListener(@NonNull OnLoadMoreListener listener) { 80 | this(listener, DEFAULT_VISIBLE_THRESOLD); 81 | } 82 | 83 | /** 84 | * Creates ScrollListener for implementing lazy loading list (endless list) 85 | * 86 | * @param listener the callback {@link OnLoadMoreListener} 87 | * @param visibleThreshold the amount of items. If there are less then visibleThreshold items 88 | * after last visible item in recycler view 89 | * and {@link OnLoadMoreListener#isLoading()} returns false, 90 | * then {@link OnLoadMoreListener#onLoadMore()} will be called. 91 | */ 92 | public LoadMoreScrollListener(@NonNull OnLoadMoreListener listener, int visibleThreshold) { 93 | mMoreListener = listener; 94 | mVisibleThreshold = visibleThreshold; 95 | } 96 | 97 | @Override 98 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 99 | super.onScrolled(recyclerView, dx, dy); 100 | 101 | if (dy < 0) return; 102 | 103 | final LayoutManager layoutManager = getLayoutManager(recyclerView); 104 | if (layoutManager == null) return; 105 | 106 | visibleItemCount = layoutManager.getChildCount(); 107 | totalItemCount = layoutManager.getItemCount(); 108 | firstVisibleItem = getFirstVisibleItemPosition(layoutManager); 109 | lastVisibleItem = firstVisibleItem + visibleItemCount - 1; 110 | 111 | if (!mMoreListener.isLoading() 112 | && lastVisibleItem >= (totalItemCount - mVisibleThreshold)) { 113 | // End has been reached 114 | mMoreListener.onLoadMore(); 115 | } 116 | } 117 | 118 | private int getFirstVisibleItemPosition(LayoutManager layoutManager) { 119 | int pos = 0; 120 | if (layoutManager instanceof LinearLayoutManager) { 121 | pos = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); 122 | } else if (layoutManager instanceof StaggeredGridLayoutManager) { 123 | pos = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(null)[0]; 124 | } 125 | return pos; 126 | } 127 | 128 | private LayoutManager getLayoutManager(RecyclerView recyclerView) { 129 | if (recyclerView != null) { 130 | return recyclerView.getLayoutManager(); 131 | } 132 | return null; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/adapter/TwoWayLoadingScrollListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.adapter; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.v7.widget.LinearLayoutManager; 21 | import android.support.v7.widget.RecyclerView; 22 | import android.support.v7.widget.StaggeredGridLayoutManager; 23 | 24 | /** 25 | * RecyclerView ScrollListener for implementing two-way lazy loading list (endless list) 26 | */ 27 | public class TwoWayLoadingScrollListener extends RecyclerView.OnScrollListener { 28 | 29 | private static final int DEFAULT_VISIBLE_THRESOLD = 2; 30 | private final OnLoadMoreListener mMoreListener; 31 | 32 | private OnPositionChangeListener mPositionChangeListener; 33 | private int mVisibleThreshold; // The minimum amount of items to have below your current scroll position before loading more. 34 | int firstVisibleItem, lastVisibleItem, oldFirstVisibleItem, oldLastVisibleItem, visibleItemCount, totalItemCount; 35 | 36 | private RecyclerView.LayoutManager mLayoutManager; 37 | 38 | public interface OnLoadMoreListener { 39 | void onLoadMoreForward(); 40 | void onLoadMoreBackward(); 41 | boolean isLoadingForward(); 42 | boolean isLoadingBackward(); 43 | } 44 | 45 | public interface OnPositionChangeListener { 46 | void onVisiblePositionChanged(int firstVisibleItem, int lastVisibleItem); 47 | } 48 | 49 | 50 | public TwoWayLoadingScrollListener(@NonNull OnLoadMoreListener listener) { 51 | this(listener, null, DEFAULT_VISIBLE_THRESOLD); 52 | } 53 | 54 | public TwoWayLoadingScrollListener(@NonNull OnLoadMoreListener listener, int visibleThreshold) { 55 | this(listener, null, visibleThreshold); 56 | } 57 | 58 | public TwoWayLoadingScrollListener(@NonNull OnLoadMoreListener listener, OnPositionChangeListener positionChangeListener, int visibleThreshold) { 59 | mMoreListener = listener; 60 | mPositionChangeListener = positionChangeListener; 61 | mVisibleThreshold = visibleThreshold; 62 | } 63 | 64 | @Override 65 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 66 | super.onScrolled(recyclerView, dx, dy); 67 | 68 | // if (dy < 0) return; 69 | 70 | getLayoutManager(recyclerView); 71 | if (mLayoutManager == null) return; 72 | 73 | visibleItemCount = mLayoutManager.getChildCount(); 74 | totalItemCount = mLayoutManager.getItemCount(); 75 | firstVisibleItem = getFirstVisibleItemPosition(); 76 | lastVisibleItem = firstVisibleItem + visibleItemCount - 1; 77 | if (mPositionChangeListener != null && (firstVisibleItem != oldFirstVisibleItem || lastVisibleItem != oldLastVisibleItem)) { 78 | mPositionChangeListener.onVisiblePositionChanged(firstVisibleItem, lastVisibleItem); 79 | oldFirstVisibleItem = firstVisibleItem; 80 | oldLastVisibleItem = lastVisibleItem; 81 | } 82 | 83 | if (!mMoreListener.isLoadingBackward() 84 | && firstVisibleItem <= mVisibleThreshold){ 85 | // Start has been reached 86 | mMoreListener.onLoadMoreBackward(); 87 | 88 | } 89 | if (!mMoreListener.isLoadingForward() 90 | && lastVisibleItem >= (totalItemCount - mVisibleThreshold)) { 91 | 92 | // End has been reached 93 | mMoreListener.onLoadMoreForward(); 94 | } 95 | } 96 | 97 | private int getFirstVisibleItemPosition() { 98 | int pos = 0; 99 | if (mLayoutManager instanceof LinearLayoutManager) { 100 | pos = ((LinearLayoutManager) mLayoutManager).findFirstVisibleItemPosition(); 101 | } else if (mLayoutManager instanceof StaggeredGridLayoutManager) { 102 | pos = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(null)[0]; 103 | } 104 | return pos; 105 | } 106 | 107 | private void getLayoutManager(RecyclerView _recyclerView) { 108 | if (_recyclerView != null) { 109 | mLayoutManager = _recyclerView.getLayoutManager(); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/delegate/ActionAdapterDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.delegate; 18 | 19 | import android.databinding.ViewDataBinding; 20 | 21 | import com.drextended.actionhandler.listener.ActionClickListener; 22 | 23 | /** 24 | * Base AdapterDelegate to use with data binding and with ability to set actionHandler 25 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 26 | * and on Action-Handler Library by Roman Donchenko https://github.com/drstranges/ActionHandler 27 | * 28 | * @param The type of the data source 29 | * @param The type of View Data Binding 30 | */ 31 | public abstract class ActionAdapterDelegate extends BaseListBindingAdapterDelegate { 32 | 33 | protected ActionClickListener mActionHandler; 34 | 35 | public ActionAdapterDelegate(final ActionClickListener actionHandler) { 36 | mActionHandler = actionHandler; 37 | } 38 | 39 | public ActionClickListener getActionHandler() { 40 | return mActionHandler; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/delegate/BaseBindingAdapterDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.delegate; 18 | 19 | import android.databinding.ViewDataBinding; 20 | import android.support.annotation.NonNull; 21 | import android.support.v7.widget.RecyclerView; 22 | import android.view.ViewGroup; 23 | 24 | import com.drextended.rvdatabinding.adapter.BindingHolder; 25 | import com.hannesdorfmann.adapterdelegates2.AdapterDelegate; 26 | 27 | /** 28 | * Base AdapterDelegate to use with data binding 29 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 30 | * 31 | * @param The type of the data source 32 | * @param The type of View Data Binding 33 | */ 34 | public abstract class BaseBindingAdapterDelegate implements AdapterDelegate { 35 | 36 | 37 | @NonNull 38 | @Override 39 | public abstract BindingHolder onCreateViewHolder(ViewGroup parent); 40 | 41 | @Override 42 | public void onBindViewHolder(@NonNull T items, int position, @NonNull RecyclerView.ViewHolder holder) { 43 | //noinspection unchecked 44 | final BindingHolder bindingHolder = (BindingHolder) holder; 45 | onBindViewHolder(items, position, bindingHolder); 46 | bindingHolder.getBinding().executePendingBindings(); 47 | } 48 | 49 | public abstract void onBindViewHolder(@NonNull T items, int position, @NonNull BindingHolder holder); 50 | } 51 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/delegate/BaseListBindingAdapterDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.delegate; 18 | 19 | import android.databinding.ViewDataBinding; 20 | 21 | import java.util.List; 22 | 23 | import static android.support.v7.widget.RecyclerView.NO_ID; 24 | 25 | /** 26 | * Base AdapterDelegate for items with ids 27 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 28 | * 29 | * @param The type of the data source 30 | * @param The type of View Data Binding 31 | */ 32 | public abstract class BaseListBindingAdapterDelegate extends BaseBindingAdapterDelegate, VB> implements IdHolder> { 33 | 34 | @Override 35 | public long getItemId(final List items, final int position) { 36 | return NO_ID; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/delegate/IdHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.delegate; 18 | 19 | /** 20 | * Interface to help BindableAdapter getting itemId for items 21 | * You must implementing this interface in you custom AdapterDelegates 22 | * if you want Adapter to be aware of itemIds. 23 | * 24 | * @param the type of data source 25 | */ 26 | public interface IdHolder { 27 | 28 | /** 29 | * Get stable id for item in data source by position 30 | * 31 | * @param items data source 32 | * @param position item position in the data source 33 | * @return stable item id 34 | */ 35 | long getItemId(T items, int position); 36 | } 37 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/delegate/ModelActionItemDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.delegate; 18 | 19 | import android.databinding.ViewDataBinding; 20 | import android.support.annotation.LayoutRes; 21 | import android.support.annotation.NonNull; 22 | import android.view.ViewGroup; 23 | 24 | import com.drextended.actionhandler.listener.ActionClickListener; 25 | import com.drextended.rvdatabinding.BR; 26 | import com.drextended.rvdatabinding.adapter.BindingHolder; 27 | 28 | /** 29 | * Generic ActionDelegate. You can use this ActionDelegate if you do not want to implement custom one. 30 | * With ability to set actionHandler. 31 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 32 | * and on Action-Handler Library by Roman Donchenko https://github.com/drstranges/ActionHandler 33 | * 34 | * @param The type of the data source 35 | */ 36 | public class ModelActionItemDelegate extends ModelItemDelegate { 37 | 38 | protected ActionClickListener mActionHandler; 39 | protected int mActionHandlerId = BR.actionHandler; 40 | 41 | public ModelActionItemDelegate(ActionClickListener actionHandler, @NonNull Class modelClass, @LayoutRes int itemLayoutResId) { 42 | super(modelClass, itemLayoutResId); 43 | mActionHandler = actionHandler; 44 | } 45 | 46 | public ModelActionItemDelegate(ActionClickListener actionHandler, @NonNull Class modelClass, @LayoutRes int itemLayoutResId, int modelId) { 47 | super(modelClass, itemLayoutResId, modelId); 48 | mActionHandler = actionHandler; 49 | } 50 | 51 | public ModelActionItemDelegate(ActionClickListener actionHandler, @NonNull Class modelClass, @LayoutRes int itemLayoutResId, int modelId, int actionHandlerId) { 52 | super(modelClass, itemLayoutResId, modelId); 53 | mActionHandler = actionHandler; 54 | if (actionHandlerId != 0) mActionHandlerId = actionHandlerId; 55 | } 56 | 57 | public ModelActionItemDelegate(ActionClickListener actionHandler, @LayoutRes int itemLayoutResId, int modelId, ViewTypeClause viewTypeClause) { 58 | super(itemLayoutResId, modelId, viewTypeClause); 59 | mActionHandler = actionHandler; 60 | } 61 | 62 | public ModelActionItemDelegate(ActionClickListener actionHandler, @LayoutRes int itemLayoutResId, int modelId, int actionHandlerId, ViewTypeClause viewTypeClause) { 63 | super(itemLayoutResId, modelId, viewTypeClause); 64 | mActionHandler = actionHandler; 65 | if (actionHandlerId != 0) mActionHandlerId = actionHandlerId; 66 | } 67 | 68 | @NonNull 69 | @Override 70 | public BindingHolder onCreateViewHolder(ViewGroup parent) { 71 | BindingHolder holder = super.onCreateViewHolder(parent); 72 | final ActionClickListener actionHandler = getActionHandler(); 73 | if (actionHandler != null) { 74 | holder.getBinding().setVariable(mActionHandlerId, actionHandler); 75 | } 76 | return holder; 77 | } 78 | 79 | public ActionClickListener getActionHandler() { 80 | return mActionHandler; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/java/com/drextended/rvdatabinding/delegate/ModelItemDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.drextended.rvdatabinding.delegate; 18 | 19 | import android.databinding.ViewDataBinding; 20 | import android.support.annotation.LayoutRes; 21 | import android.support.annotation.NonNull; 22 | import android.view.LayoutInflater; 23 | import android.view.ViewGroup; 24 | 25 | import com.drextended.rvdatabinding.BR; 26 | import com.drextended.rvdatabinding.R; 27 | import com.drextended.rvdatabinding.adapter.BindingHolder; 28 | 29 | import java.util.List; 30 | 31 | /** 32 | * Generic ActionDelegate. You can use this ActionDelegate if you do not want to implement custom one 33 | * Based on AdapterDelegates Library by Hannes Dorfmann https://github.com/sockeqwe/AdapterDelegates 34 | * 35 | * @param The type of the data source 36 | */ 37 | public class ModelItemDelegate extends BaseListBindingAdapterDelegate { 38 | 39 | private final int mModelId; 40 | private final int mItemLayoutResId; 41 | private final ViewTypeClause mViewTypeClause; 42 | 43 | public ModelItemDelegate(@NonNull Class modelClass, @LayoutRes int itemLayoutResId) { 44 | this(itemLayoutResId, BR.model, new SimpleViewTypeClause(modelClass)); 45 | } 46 | 47 | public ModelItemDelegate(@NonNull Class modelClass, @LayoutRes int itemLayoutResId, int modelId) { 48 | this(itemLayoutResId, modelId, new SimpleViewTypeClause(modelClass)); 49 | } 50 | 51 | public ModelItemDelegate(@LayoutRes int itemLayoutResId, int modelId, ViewTypeClause viewTypeClause) { 52 | mItemLayoutResId = itemLayoutResId != 0 ? itemLayoutResId : R.layout.item_fallback; 53 | mViewTypeClause = viewTypeClause; 54 | mModelId = modelId != 0 ? modelId : BR.model; 55 | } 56 | 57 | @Override 58 | public boolean isForViewType(@NonNull List items, int position) { 59 | return mViewTypeClause.isForViewType(items, position); 60 | } 61 | 62 | @NonNull 63 | @Override 64 | public BindingHolder onCreateViewHolder(ViewGroup parent) { 65 | return BindingHolder.newInstance(mItemLayoutResId, 66 | LayoutInflater.from(parent.getContext()), parent, false); 67 | } 68 | 69 | @Override 70 | public void onBindViewHolder(@NonNull List items, int position, @NonNull BindingHolder holder) { 71 | ViewDataBinding binding = holder.getBinding(); 72 | binding.setVariable(mModelId, items.get(position)); 73 | binding.executePendingBindings(); 74 | } 75 | 76 | public interface ViewTypeClause { 77 | boolean isForViewType(List items, int position); 78 | } 79 | 80 | public static class SimpleViewTypeClause implements ViewTypeClause { 81 | 82 | private final Class mClass; 83 | 84 | public SimpleViewTypeClause(@NonNull Class aClass) { 85 | mClass = aClass; 86 | } 87 | 88 | 89 | @Override 90 | public boolean isForViewType(List items, int position) { 91 | return mClass.isAssignableFrom(items.get(position).getClass()); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/res/layout/item_fallback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 13 | 14 | 15 | 21 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4dp 4 | -------------------------------------------------------------------------------- /rvdatabinding/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DataBindingForRecyclerView 3 | 4 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.2" 6 | 7 | dataBinding { 8 | enabled = true 9 | } 10 | 11 | defaultConfig { 12 | applicationId "com.drextended.rvdbsample" 13 | minSdkVersion 16 14 | targetSdkVersion 24 15 | versionCode 1 16 | versionName "1.0" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | 29 | compile project(path: ':rvdatabinding') 30 | compile 'com.android.support:appcompat-v7:24.2.0' 31 | compile 'com.android.support:recyclerview-v7:24.2.0' 32 | compile 'com.android.support:cardview-v7:24.2.0' 33 | compile 'com.android.support:design:24.2.0' 34 | compile 'com.github.bumptech.glide:glide:3.7.0' 35 | 36 | } 37 | -------------------------------------------------------------------------------- /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:\Android_Env\android-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 | -------------------------------------------------------------------------------- /sample/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/sample/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/model/ActionType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.model; 17 | 18 | /** 19 | * Shared action types 20 | */ 21 | public class ActionType { 22 | public static final String OPEN = "open"; 23 | public static final String MENU = "menu"; 24 | } 25 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/model/Advertisement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.model; 17 | 18 | /** 19 | * Advertisement model. For getting unique images used loremflickr.com 20 | */ 21 | public class Advertisement implements BaseModel { 22 | public long id; 23 | public String label; 24 | public String image; 25 | 26 | public Advertisement(final String label) { 27 | this.label = label; 28 | this.id = label.hashCode(); 29 | this.image = "http://loremflickr.com/300/100/sport?random=" + this.id; 30 | } 31 | 32 | @Override 33 | public long getId() { 34 | return id; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return label; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/model/BaseModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.model; 17 | 18 | /** 19 | * Base model 20 | */ 21 | public interface BaseModel { 22 | long getId(); 23 | } 24 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/model/Location.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.model; 17 | 18 | /** 19 | * Location model. For getting unique images used loremflickr.com 20 | */ 21 | 22 | public class Location implements BaseModel { 23 | public long id; 24 | public String name; 25 | public String image; 26 | 27 | public Location(final String name) { 28 | this.name = name; 29 | this.id = name.hashCode(); 30 | this.image = "http://loremflickr.com/100/100/" + name + "?random=" + this.id; 31 | } 32 | 33 | @Override 34 | public long getId() { 35 | return id; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return name; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/model/User.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.model; 17 | 18 | /** 19 | * User model. For getting unique avatars used www.avatarpro.biz 20 | */ 21 | public class User implements BaseModel { 22 | public long id; 23 | public String name; 24 | public String avatar; 25 | 26 | public User(final String name) { 27 | this.name = name; 28 | this.id = name.hashCode(); 29 | this.avatar = "http://www.avatarpro.biz/avatar/" + name.hashCode(); 30 | } 31 | 32 | @Override 33 | public long getId() { 34 | return id; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return name; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/util/CircleBorderedTransform.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.util; 17 | 18 | import android.graphics.Bitmap; 19 | import android.graphics.BitmapShader; 20 | import android.graphics.Canvas; 21 | import android.graphics.CornerPathEffect; 22 | import android.graphics.Matrix; 23 | import android.graphics.Paint; 24 | import android.graphics.PathEffect; 25 | 26 | import com.bumptech.glide.load.Transformation; 27 | import com.bumptech.glide.load.engine.Resource; 28 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 29 | import com.bumptech.glide.load.resource.bitmap.BitmapResource; 30 | 31 | /** 32 | * Custom Glide Transform for make circle image with colored border 33 | */ 34 | public class CircleBorderedTransform implements Transformation { 35 | 36 | private final int mBorderColor; 37 | private BitmapPool mBitmapPool; 38 | private PathEffect mPathEffect = new CornerPathEffect(10); 39 | 40 | public CircleBorderedTransform(final BitmapPool pool, final int borderColor) { 41 | mBitmapPool = pool; 42 | mBorderColor = borderColor; 43 | } 44 | 45 | @Override 46 | public Resource transform(Resource resource, int outWidth, int outHeight) { 47 | Bitmap source = resource.get(); 48 | int size = Math.min(source.getWidth(), source.getHeight()); 49 | 50 | int width = (source.getWidth() - size) / 2; 51 | int height = (source.getHeight() - size) / 2; 52 | 53 | Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888); 54 | if (bitmap == null) { 55 | bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); 56 | } 57 | 58 | Canvas canvas = new Canvas(bitmap); 59 | Paint paint = new Paint(); 60 | BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, 61 | BitmapShader.TileMode.CLAMP); 62 | if (width != 0 || height != 0) { 63 | Matrix matrix = new Matrix(); 64 | matrix.setTranslate(-width, -height); 65 | shader.setLocalMatrix(matrix); 66 | } 67 | paint.setShader(shader); 68 | paint.setAntiAlias(true); 69 | 70 | float r = size / 2f; 71 | float stroke = getStrokeWidth(r); 72 | canvas.drawCircle(r, r, r, paint); 73 | 74 | preparePaintForCircleBorder(paint, stroke); 75 | 76 | canvas.drawCircle(r, r, r - stroke / 2f, paint); 77 | 78 | return BitmapResource.obtain(bitmap, mBitmapPool); 79 | } 80 | 81 | private void preparePaintForCircleBorder(final Paint _paint, final float _stroke) { 82 | _paint.setShader(null); 83 | _paint.setColor(mBorderColor); 84 | _paint.setStyle(Paint.Style.STROKE); 85 | _paint.setStrokeJoin(Paint.Join.ROUND); 86 | _paint.setStrokeCap(Paint.Cap.ROUND); 87 | _paint.setPathEffect(mPathEffect); 88 | _paint.setStrokeWidth(_stroke); 89 | } 90 | 91 | /** 92 | * @param radius - circle radius 93 | * @return - the stroke width based on the radius size 94 | */ 95 | private float getStrokeWidth(final float radius) { 96 | return radius * 0.06f; 97 | } 98 | 99 | @Override 100 | public String getId() { 101 | return "CircleBorderedTransform"; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/util/Converters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.util; 17 | 18 | import android.app.Activity; 19 | import android.content.Context; 20 | import android.content.ContextWrapper; 21 | import android.databinding.BindingAdapter; 22 | import android.graphics.Color; 23 | import android.graphics.drawable.Drawable; 24 | import android.support.v4.content.ContextCompat; 25 | import android.text.TextUtils; 26 | import android.view.View; 27 | import android.view.ViewGroup; 28 | import android.view.ViewParent; 29 | import android.widget.ImageView; 30 | 31 | import com.bumptech.glide.DrawableRequestBuilder; 32 | import com.bumptech.glide.Glide; 33 | import com.bumptech.glide.RequestManager; 34 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 35 | import com.bumptech.glide.signature.StringSignature; 36 | import com.drextended.rvdbsample.R; 37 | 38 | /** 39 | * All Binding Adapters and converters in one place 40 | */ 41 | public class Converters { 42 | 43 | @BindingAdapter(value = {"glidePath", "glidePlaceholder", "glideSignature", "glideCacheStrategy", "glideCrossFadeDisabled", "glideAnimation", "glideTransform"}, requireAll = false) 44 | public static void setImageUri(ImageView imageView, String path, Drawable placeholder, String glideSignature, String glideCacheStrategy, boolean crossFadeDisabled, Integer animationResId, String glideTransform) { 45 | Context context = imageView.getContext(); 46 | 47 | if (context instanceof Activity && ((Activity) context).isFinishing()) return; 48 | if (context instanceof ContextWrapper) { 49 | final Context baseContext = ((ContextWrapper) context).getBaseContext(); 50 | if (baseContext instanceof Activity && ((Activity) baseContext).isFinishing()) return; 51 | } 52 | boolean isEmptyPath = TextUtils.isEmpty(path); 53 | if (isEmptyPath) { 54 | if (placeholder != null) { 55 | imageView.setImageDrawable(placeholder); 56 | } 57 | return; 58 | } 59 | try { 60 | RequestManager glide = Glide.with(context); 61 | DrawableRequestBuilder request = glide.load(path); 62 | 63 | if (placeholder != null) { 64 | if (!crossFadeDisabled && animationResId == null) request.crossFade(); 65 | request.placeholder(placeholder); 66 | } 67 | if (animationResId != null) { 68 | request.animate(animationResId); 69 | } 70 | if (!TextUtils.isEmpty(glideSignature)) { 71 | request.signature(new StringSignature(glideSignature)); 72 | } 73 | if (glideTransform != null) { 74 | switch (glideTransform) { 75 | case "CIRCLE": 76 | request.bitmapTransform( 77 | new CircleBorderedTransform(Glide.get(context).getBitmapPool(), Color.WHITE)); 78 | break; 79 | case "BLUR": 80 | break; 81 | } 82 | } 83 | 84 | if (!TextUtils.isEmpty(glideCacheStrategy)) { 85 | request.diskCacheStrategy(DiskCacheStrategy.valueOf(glideCacheStrategy)); 86 | } 87 | 88 | request.into(imageView); 89 | } catch (IllegalArgumentException e) { 90 | e.printStackTrace(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/util/DummyDataProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.util; 17 | 18 | import com.drextended.rvdbsample.model.Advertisement; 19 | import com.drextended.rvdbsample.model.Location; 20 | import com.drextended.rvdbsample.model.User; 21 | 22 | import java.util.Arrays; 23 | import java.util.List; 24 | 25 | /** 26 | * Provider of fake data 27 | */ 28 | public class DummyDataProvider { 29 | 30 | public static List getUsers() { 31 | return Arrays.asList( 32 | new User("Tarik Dickerson"), 33 | new User("Hilel Hart"), 34 | new User("Dane Warner"), 35 | new User("Lamar Gross"), 36 | new User("Driscoll Lancaster"), 37 | new User("Finn Kelly"), 38 | new User("Quinlan Burt"), 39 | new User("Ryan Dotson"), 40 | new User("Zachary Benjamin"), 41 | new User("Connor Merrill"), 42 | new User(" Jeremy Alford"), 43 | new User("Demetrius Hodge"), 44 | new User("Troy Ware"), 45 | new User("Jared Villarreal"), 46 | new User("Slade Romero"), 47 | new User("Keane Franks") 48 | ); 49 | } 50 | 51 | public static Advertisement getAdvertisment(int index) { 52 | return new Advertisement("This is Advertisment #" + index); 53 | } 54 | 55 | public static List getLocations() { 56 | return Arrays.asList( 57 | new Location("Amsterdam"), 58 | new Location("Paris"), 59 | new Location("Rome"), 60 | new Location("London"), 61 | new Location("New York"), 62 | new Location("Los Angeles"), 63 | new Location("Sydney"), 64 | new Location("Copenhagen"), 65 | new Location("Dubai"), 66 | new Location("Berlin"), 67 | new Location("Budapest"), 68 | new Location("Tokyo") 69 | ); 70 | } 71 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/util/SimpleCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.util; 17 | 18 | /** 19 | * The simple callback 20 | */ 21 | public interface SimpleCallback { 22 | 23 | void showMessage(String message); 24 | } 25 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/view/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.view; 17 | 18 | import android.databinding.DataBindingUtil; 19 | import android.os.Bundle; 20 | import android.support.v4.app.Fragment; 21 | import android.support.v4.app.FragmentStatePagerAdapter; 22 | import android.support.v7.app.AppCompatActivity; 23 | 24 | import com.drextended.rvdbsample.R; 25 | import com.drextended.rvdbsample.databinding.ActivityMainBinding; 26 | 27 | public class MainActivity extends AppCompatActivity { 28 | 29 | private ActivityMainBinding mBinding; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main); 35 | initViewPager(); 36 | } 37 | 38 | private void initViewPager() { 39 | mBinding.viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) { 40 | @Override 41 | public Fragment getItem(final int position) { 42 | return PageFragment.newInstance(position); 43 | } 44 | 45 | @Override 46 | public CharSequence getPageTitle(final int position) { 47 | return getString(PageFragment.getPageTitleResId(position)); 48 | } 49 | 50 | @Override 51 | public int getCount() { 52 | return 3; 53 | } 54 | }); 55 | mBinding.tabLayout.setupWithViewPager(mBinding.viewPager); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/view/PageFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.view; 17 | 18 | 19 | import android.databinding.DataBindingUtil; 20 | import android.os.Bundle; 21 | import android.support.design.widget.Snackbar; 22 | import android.support.v4.app.Fragment; 23 | import android.view.LayoutInflater; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | 27 | import com.drextended.rvdbsample.R; 28 | import com.drextended.rvdbsample.databinding.FragmentPageBinding; 29 | import com.drextended.rvdbsample.util.SimpleCallback; 30 | import com.drextended.rvdbsample.viewmodel.AllInOneListViewModel; 31 | import com.drextended.rvdbsample.viewmodel.ListViewModel; 32 | import com.drextended.rvdbsample.viewmodel.LocationListViewModel; 33 | import com.drextended.rvdbsample.viewmodel.UserListViewModel; 34 | 35 | public class PageFragment extends Fragment implements SimpleCallback { 36 | 37 | private static final String ARG_PAGE = "page"; 38 | 39 | private ListViewModel mViewModel; 40 | private FragmentPageBinding mBinding; 41 | 42 | public static PageFragment newInstance(int page) { 43 | PageFragment fragment = new PageFragment(); 44 | Bundle args = new Bundle(); 45 | args.putInt(ARG_PAGE, page); 46 | fragment.setArguments(args); 47 | return fragment; 48 | } 49 | 50 | @Override 51 | public void onCreate(Bundle savedInstanceState) { 52 | super.onCreate(savedInstanceState); 53 | int page = 0; 54 | if (getArguments() != null) page = getArguments().getInt(ARG_PAGE, 0); 55 | 56 | switch (page) { 57 | case 0: 58 | mViewModel = new UserListViewModel(getContext(), this); 59 | break; 60 | case 1: 61 | mViewModel = new LocationListViewModel(getContext()); 62 | break; 63 | case 2: 64 | default: 65 | mViewModel = new AllInOneListViewModel(getContext()); 66 | break; 67 | } 68 | } 69 | 70 | @Override 71 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 72 | mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_page, container, false); 73 | mBinding.setViewModel(mViewModel); 74 | return mBinding.getRoot(); 75 | } 76 | 77 | @Override 78 | public void onDestroy() { 79 | mViewModel.onDestroy(); 80 | super.onDestroy(); 81 | } 82 | 83 | public static int getPageTitleResId(final int page) { 84 | switch (page) { 85 | case 0: return R.string.page_users; 86 | case 1: return R.string.page_locations; 87 | case 2: 88 | default: return R.string.page_all_in_one; 89 | } 90 | } 91 | 92 | @Override 93 | public void showMessage(final String message) { 94 | Snackbar.make(mBinding.getRoot(), message, Snackbar.LENGTH_SHORT).show(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/AllInOneListViewModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel; 17 | 18 | import android.content.Context; 19 | 20 | import com.drextended.actionhandler.ActionHandler; 21 | import com.drextended.actionhandler.listener.ActionClickListener; 22 | import com.drextended.rvdatabinding.ListConfig; 23 | import com.drextended.rvdatabinding.adapter.BindableAdapter; 24 | import com.drextended.rvdatabinding.delegate.ModelActionItemDelegate; 25 | import com.drextended.rvdbsample.R; 26 | import com.drextended.rvdbsample.model.ActionType; 27 | import com.drextended.rvdbsample.model.Advertisement; 28 | import com.drextended.rvdbsample.model.BaseModel; 29 | import com.drextended.rvdbsample.model.Location; 30 | import com.drextended.rvdbsample.model.User; 31 | import com.drextended.rvdbsample.util.DummyDataProvider; 32 | import com.drextended.rvdbsample.viewmodel.action.ShowToastAction; 33 | import com.drextended.rvdbsample.BR; 34 | 35 | import java.util.ArrayList; 36 | import java.util.Collections; 37 | import java.util.List; 38 | 39 | /** 40 | * Viewmodel for page with All item types in one list 41 | */ 42 | public class AllInOneListViewModel implements ListViewModel { 43 | 44 | private ListConfig mListConfig; 45 | private BindableAdapter> mAdapter; 46 | 47 | public AllInOneListViewModel(Context context) { 48 | 49 | final ActionClickListener actionHandler = new ActionHandler.Builder() 50 | .addAction(ActionType.OPEN, new ShowToastAction()) 51 | .addAction(ActionType.MENU, new ShowToastAction()) 52 | //.addAction(null, new TrackAction()) // fires for any actionType 53 | .build(); 54 | 55 | //noinspection unchecked 56 | mAdapter = new BindableAdapter<>( 57 | // new UserDelegate(actionHandler), you do not need even create custom delegate 58 | new ModelActionItemDelegate(actionHandler, User.class, R.layout.item_user, BR.user), 59 | new ModelActionItemDelegate(actionHandler, Location.class, R.layout.item_location, BR.location), 60 | new ModelActionItemDelegate(actionHandler, Advertisement.class, R.layout.item_advertisment, BR.advertisment) 61 | ); 62 | mListConfig = new ListConfig.Builder(mAdapter) 63 | .setDefaultDividerEnabled(true) 64 | .build(context); 65 | 66 | loadData(); 67 | } 68 | 69 | @Override 70 | public ListConfig getListConfig() { 71 | return mListConfig; 72 | } 73 | 74 | @Override 75 | public void onDestroy() {} 76 | 77 | private void loadData() { 78 | mAdapter.setItems(getDummyData()); 79 | mAdapter.notifyDataSetChanged(); 80 | } 81 | 82 | private List getDummyData() { 83 | ArrayList list = new ArrayList<>(); 84 | list.addAll(DummyDataProvider.getLocations()); 85 | list.addAll(DummyDataProvider.getUsers()); 86 | 87 | Collections.shuffle(list); 88 | 89 | list.add(0, DummyDataProvider.getAdvertisment(1)); 90 | list.add(6, DummyDataProvider.getAdvertisment(2)); 91 | list.add(12, DummyDataProvider.getAdvertisment(3)); 92 | list.add(22, DummyDataProvider.getAdvertisment(4)); 93 | list.add(30, DummyDataProvider.getAdvertisment(5)); 94 | return list; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/ListViewModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel; 17 | 18 | import com.drextended.rvdatabinding.ListConfig; 19 | 20 | /** 21 | * Base viewmodel 22 | */ 23 | public interface ListViewModel { 24 | 25 | ListConfig getListConfig(); 26 | 27 | void onDestroy(); 28 | } 29 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/LocationListViewModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel; 17 | 18 | import android.content.Context; 19 | import android.support.v7.widget.GridLayoutManager; 20 | import android.support.v7.widget.RecyclerView; 21 | 22 | import com.drextended.actionhandler.ActionHandler; 23 | import com.drextended.actionhandler.listener.ActionClickListener; 24 | import com.drextended.rvdatabinding.ListConfig; 25 | import com.drextended.rvdatabinding.adapter.BindableAdapter; 26 | import com.drextended.rvdatabinding.adapter.DividerItemDecoration; 27 | import com.drextended.rvdbsample.model.ActionType; 28 | import com.drextended.rvdbsample.model.Advertisement; 29 | import com.drextended.rvdbsample.model.BaseModel; 30 | import com.drextended.rvdbsample.util.DummyDataProvider; 31 | import com.drextended.rvdbsample.viewmodel.action.OpenLocationAction; 32 | import com.drextended.rvdbsample.viewmodel.action.ShowToastAction; 33 | import com.drextended.rvdbsample.viewmodel.delegate.AdvertisementDelegate; 34 | import com.drextended.rvdbsample.viewmodel.delegate.LocationDelegate; 35 | 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | 39 | import static com.drextended.rvdatabinding.adapter.DividerItemDecoration.SPACE_BOTTOM; 40 | import static com.drextended.rvdatabinding.adapter.DividerItemDecoration.SPACE_LEFT; 41 | import static com.drextended.rvdatabinding.adapter.DividerItemDecoration.SPACE_RIGHT; 42 | import static com.drextended.rvdatabinding.adapter.DividerItemDecoration.SPACE_TOP; 43 | 44 | /** 45 | * Viewmodel for page with Location and Advertisement item types in one list 46 | */ 47 | public class LocationListViewModel implements ListViewModel { 48 | 49 | private ListConfig mListConfig; 50 | private BindableAdapter> mAdapter; 51 | 52 | public LocationListViewModel(Context context) { 53 | final ActionClickListener actionHandler = new ActionHandler.Builder() 54 | .addAction(ActionType.OPEN, new OpenLocationAction()) 55 | .addAction(ActionType.MENU, new ShowToastAction()) 56 | .build(); 57 | mAdapter = new BindableAdapter<>( 58 | new LocationDelegate(actionHandler), 59 | new AdvertisementDelegate(actionHandler) 60 | ); 61 | mListConfig = createListConfig(context, mAdapter); 62 | 63 | loadData(); 64 | } 65 | 66 | private ListConfig createListConfig(final Context context, final RecyclerView.Adapter adapter) { 67 | final int divider = context.getResources().getDimensionPixelSize(com.drextended.rvdatabinding.R.dimen.rvdb_list_divider_size_default); 68 | return new ListConfig.Builder(adapter) 69 | .setLayoutManagerProvider(new ListConfig.SimpleGridLayoutManagerProvider(2, new GridLayoutManager.SpanSizeLookup() { 70 | @Override 71 | public int getSpanSize(final int position) { 72 | return mAdapter.getItems().get(position) instanceof Advertisement ? 2 : 1; 73 | } 74 | })) 75 | .addItemDecoration(new DividerItemDecoration(divider, SPACE_LEFT|SPACE_TOP|SPACE_RIGHT|SPACE_BOTTOM)) 76 | .build(context); 77 | } 78 | 79 | @Override 80 | public ListConfig getListConfig() { 81 | return mListConfig; 82 | } 83 | 84 | @Override 85 | public void onDestroy() {} 86 | 87 | private void loadData() { 88 | mAdapter.setItems(getDummyData()); 89 | mAdapter.notifyDataSetChanged(); 90 | } 91 | 92 | private List getDummyData() { 93 | ArrayList list = new ArrayList<>(); 94 | list.addAll(DummyDataProvider.getLocations()); 95 | list.add(0, DummyDataProvider.getAdvertisment(4)); 96 | list.add(9, DummyDataProvider.getAdvertisment(5)); 97 | return list; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/UserListViewModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel; 17 | 18 | import android.content.Context; 19 | import android.view.View; 20 | 21 | import com.drextended.actionhandler.listener.ActionClickListener; 22 | import com.drextended.rvdatabinding.ListConfig; 23 | import com.drextended.rvdatabinding.adapter.BindableAdapter; 24 | import com.drextended.rvdbsample.model.ActionType; 25 | import com.drextended.rvdbsample.model.BaseModel; 26 | import com.drextended.rvdbsample.util.DummyDataProvider; 27 | import com.drextended.rvdbsample.util.SimpleCallback; 28 | import com.drextended.rvdbsample.viewmodel.delegate.AdvertisementDelegate; 29 | import com.drextended.rvdbsample.viewmodel.delegate.UserDelegate; 30 | 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | /** 35 | * Viewmodel for page with User and Advertisement item types in one list 36 | */ 37 | public class UserListViewModel implements ListViewModel, ActionClickListener { 38 | 39 | private ListConfig mListConfig; 40 | private BindableAdapter> mAdapter; 41 | private SimpleCallback mCallback; 42 | 43 | public UserListViewModel(Context context, final SimpleCallback callback) { 44 | mCallback = callback; 45 | mAdapter = new BindableAdapter<>( 46 | new UserDelegate(this), 47 | new AdvertisementDelegate(this) 48 | ); 49 | mListConfig = new ListConfig.Builder(mAdapter) 50 | .setDefaultDividerEnabled(true) 51 | .build(context); 52 | loadData(); 53 | } 54 | 55 | @Override 56 | public ListConfig getListConfig() { 57 | return mListConfig; 58 | } 59 | 60 | @Override 61 | public void onDestroy() { 62 | mCallback = null; 63 | } 64 | 65 | private void loadData() { 66 | mAdapter.setItems(getDummyData()); 67 | mAdapter.notifyDataSetChanged(); 68 | } 69 | 70 | private List getDummyData() { 71 | ArrayList list = new ArrayList<>(); 72 | list.addAll(DummyDataProvider.getUsers()); 73 | list.add(0, DummyDataProvider.getAdvertisment(1)); 74 | list.add(6, DummyDataProvider.getAdvertisment(2)); 75 | list.add(12, DummyDataProvider.getAdvertisment(3)); 76 | return list; 77 | } 78 | 79 | @Override 80 | public void onActionClick(final View view, final String actionType, final Object model) { 81 | switch (actionType) { 82 | case ActionType.OPEN: 83 | mCallback.showMessage("Short click by " + model.toString()); 84 | break; 85 | case ActionType.MENU: 86 | mCallback.showMessage("Long click by " + model.toString()); 87 | break; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/action/OpenLocationAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel.action; 17 | 18 | import android.content.Context; 19 | import android.support.annotation.Nullable; 20 | import android.view.View; 21 | import android.widget.Toast; 22 | 23 | import com.drextended.actionhandler.action.BaseAction; 24 | import com.drextended.rvdbsample.model.Location; 25 | 26 | /** 27 | * Action to handle click by location 28 | */ 29 | public class OpenLocationAction extends BaseAction { 30 | 31 | @Override 32 | public boolean isModelAccepted(final Object model) { 33 | return model instanceof Location; 34 | } 35 | 36 | @Override 37 | public void onFireAction(final Context context, @Nullable final View view, @Nullable final String actionType, @Nullable final Location model) { 38 | //noinspection ConstantConditions 39 | Toast.makeText(context, "Click by Location: " + model.name, Toast.LENGTH_SHORT).show(); 40 | // open location detail screen 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/action/ShowToastAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel.action; 17 | 18 | import android.content.Context; 19 | import android.support.annotation.Nullable; 20 | import android.view.View; 21 | import android.widget.Toast; 22 | 23 | import com.drextended.actionhandler.action.BaseAction; 24 | 25 | /** 26 | * Simple action 27 | */ 28 | public class ShowToastAction extends BaseAction { 29 | @Override 30 | public boolean isModelAccepted(final Object model) { 31 | return model != null; 32 | } 33 | 34 | @Override 35 | public void onFireAction(final Context context, @Nullable final View view, @Nullable final String actionType, @Nullable final Object model) { 36 | //noinspection ConstantConditions 37 | Toast.makeText(context, "Action fired: actionType = " + actionType + ", model = " + model.toString(), Toast.LENGTH_SHORT).show(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/delegate/AdvertisementDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel.delegate; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.view.LayoutInflater; 20 | import android.view.ViewGroup; 21 | 22 | import com.drextended.actionhandler.listener.ActionClickListener; 23 | import com.drextended.rvdatabinding.adapter.BindingHolder; 24 | import com.drextended.rvdatabinding.delegate.ActionAdapterDelegate; 25 | import com.drextended.rvdatabinding.delegate.BaseListBindingAdapterDelegate; 26 | import com.drextended.rvdbsample.R; 27 | import com.drextended.rvdbsample.databinding.ItemAdvertismentBinding; 28 | import com.drextended.rvdbsample.model.Advertisement; 29 | import com.drextended.rvdbsample.model.BaseModel; 30 | 31 | import java.util.List; 32 | 33 | /** 34 | * Item Delegate to display Advertisement item 35 | */ 36 | public class AdvertisementDelegate extends ActionAdapterDelegate { 37 | 38 | public AdvertisementDelegate(final ActionClickListener actionHandler) { 39 | super(actionHandler); 40 | } 41 | 42 | @Override 43 | public boolean isForViewType(@NonNull final List items, final int position) { 44 | return items.get(position) instanceof Advertisement; 45 | } 46 | 47 | @NonNull 48 | @Override 49 | public BindingHolder onCreateViewHolder(final ViewGroup parent) { 50 | return BindingHolder.newInstance(R.layout.item_advertisment, LayoutInflater.from(parent.getContext()), parent, false); 51 | } 52 | 53 | @Override 54 | public void onBindViewHolder(@NonNull final List items, final int position, @NonNull final BindingHolder holder) { 55 | final Advertisement advertisement = (Advertisement) items.get(position); 56 | holder.getBinding().setAdvertisment(advertisement); 57 | holder.getBinding().setActionHandler(getActionHandler()); 58 | } 59 | 60 | @Override 61 | public long getItemId(final List items, final int position) { 62 | return items.get(position).getId(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/delegate/LocationDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel.delegate; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.view.LayoutInflater; 20 | import android.view.ViewGroup; 21 | 22 | import com.drextended.actionhandler.listener.ActionClickListener; 23 | import com.drextended.rvdatabinding.adapter.BindingHolder; 24 | import com.drextended.rvdatabinding.delegate.ActionAdapterDelegate; 25 | import com.drextended.rvdbsample.R; 26 | import com.drextended.rvdbsample.databinding.ItemLocationBinding; 27 | import com.drextended.rvdbsample.model.BaseModel; 28 | import com.drextended.rvdbsample.model.Location; 29 | 30 | import java.util.List; 31 | 32 | /** 33 | * Item Delegate to display Location item 34 | */ 35 | public class LocationDelegate extends ActionAdapterDelegate { 36 | 37 | public LocationDelegate(final ActionClickListener actionHandler) { 38 | super(actionHandler); 39 | } 40 | 41 | @Override 42 | public boolean isForViewType(@NonNull final List items, final int position) { 43 | return items.get(position) instanceof Location; 44 | } 45 | 46 | @NonNull 47 | @Override 48 | public BindingHolder onCreateViewHolder(final ViewGroup parent) { 49 | return BindingHolder.newInstance(R.layout.item_location, LayoutInflater.from(parent.getContext()), parent, false); 50 | } 51 | 52 | @Override 53 | public void onBindViewHolder(@NonNull final List items, final int position, @NonNull final BindingHolder holder) { 54 | final Location location = (Location) items.get(position); 55 | holder.getBinding().setLocation(location); 56 | holder.getBinding().setActionHandler(getActionHandler()); 57 | } 58 | 59 | @Override 60 | public long getItemId(final List items, final int position) { 61 | return items.get(position).getId(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drextended/rvdbsample/viewmodel/delegate/UserDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Roman Donchenko. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.drextended.rvdbsample.viewmodel.delegate; 17 | 18 | import android.support.annotation.NonNull; 19 | import android.view.LayoutInflater; 20 | import android.view.ViewGroup; 21 | 22 | import com.drextended.actionhandler.listener.ActionClickListener; 23 | import com.drextended.rvdatabinding.adapter.BindingHolder; 24 | import com.drextended.rvdatabinding.delegate.ActionAdapterDelegate; 25 | import com.drextended.rvdbsample.R; 26 | import com.drextended.rvdbsample.databinding.ItemUserBinding; 27 | import com.drextended.rvdbsample.model.BaseModel; 28 | import com.drextended.rvdbsample.model.User; 29 | 30 | import java.util.List; 31 | 32 | /** 33 | * Item Delegate to display User item 34 | */ 35 | public class UserDelegate extends ActionAdapterDelegate { 36 | 37 | public UserDelegate(final ActionClickListener actionHandler) { 38 | super(actionHandler); 39 | } 40 | 41 | @Override 42 | public boolean isForViewType(@NonNull final List items, final int position) { 43 | return items.get(position) instanceof User; 44 | } 45 | 46 | @NonNull 47 | @Override 48 | public BindingHolder onCreateViewHolder(final ViewGroup parent) { 49 | return BindingHolder.newInstance(R.layout.item_user, LayoutInflater.from(parent.getContext()), parent, false); 50 | } 51 | 52 | @Override 53 | public void onBindViewHolder(@NonNull final List items, final int position, @NonNull final BindingHolder holder) { 54 | final User user = (User) items.get(position); 55 | holder.getBinding().setUser(user); 56 | holder.getBinding().setActionHandler(getActionHandler()); 57 | } 58 | 59 | @Override 60 | public long getItemId(final List items, final int position) { 61 | return items.get(position).getId(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sample/src/main/res/anim/scale_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /sample/src/main/res/anim/slide_in_top.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/src/main/res/animator/raise.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 14 | 15 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_page.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/item_advertisment.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 20 | 21 | 22 | 30 | 31 | 35 | 36 | 45 | 46 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/item_location.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 19 | 20 | 21 | 29 | 30 | 34 | 35 | 48 | 49 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/item_user.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 19 | 20 | 21 | 29 | 30 | 34 | 35 | 49 | 50 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drstranges/DataBinding_For_RecyclerView/5f3adef06d1875351c85fc5f504dd7554e554692/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | #eee 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DataBinding for RecyclerView 3 | 4 | Users 5 | Locations 6 | All in One 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':sample', ':rvdatabinding' 2 | --------------------------------------------------------------------------------