├── .gitignore ├── Gradle.properties ├── LICENSE.md ├── README.md ├── Sample ├── .gitignore ├── AndroidManifest.xml ├── assets │ ├── arialbd.ttf │ ├── categories.json │ └── products.json ├── build.gradle ├── libs │ ├── android-support-v4.jar │ └── gson-2.2.2.jar ├── proguard-project.txt ├── project.properties ├── res │ ├── drawable-hdpi │ │ ├── ic_launcher.png │ │ └── placeholder.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── layout │ │ ├── activity_main.xml │ │ └── product_list_item.xml │ ├── values-sw600dp │ │ └── dimens.xml │ ├── values-sw720dp-land │ │ └── dimens.xml │ ├── values-v11 │ │ └── styles.xml │ ├── values-v14 │ │ └── styles.xml │ └── values │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml └── src │ └── com │ └── example │ └── bindableadaptertest │ ├── Category.java │ ├── MainActivity.java │ ├── MockImageLoader.java │ ├── MyExpandableActivity.java │ ├── Product.java │ └── ProductListAdapter.java ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── AndroidManifest.xml ├── build.gradle ├── proguard-project.txt ├── project.properties ├── res │ └── values │ │ └── strings.xml └── src │ └── com │ └── ami │ └── fundapter │ ├── BindDictionary.java │ ├── ExpandableFunDapter.java │ ├── FunDapter.java │ ├── FunDapterUtils.java │ ├── GenericViewHolder.java │ ├── extractors │ ├── BooleanExtractor.java │ ├── ChildExtractor.java │ ├── IntegerExtractor.java │ ├── LongExtractor.java │ └── StringExtractor.java │ ├── fields │ ├── BaseField.java │ ├── BaseStringField.java │ ├── CheckableField.java │ ├── ConditionalVisibilityField.java │ ├── DynamicImageField.java │ ├── ProgressBarField.java │ ├── StaticImageField.java │ └── StringField.java │ └── interfaces │ ├── CheckedChangeListener.java │ ├── DynamicImageLoader.java │ ├── FunDapterFilter.java │ ├── ItemClickListener.java │ ├── StaticImageLoader.java │ └── ViewPopulatedListener.java ├── maven_push.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Copyright: Benjamin Weiss (keyboardsurfer) https://github.com/keyboardsurfer 2 | # Under CC-BY-SA V3.0 (https://creativecommons.org/licenses/by-sa/3.0/legalcode) 3 | 4 | # built application files 5 | *.apk 6 | *.ap_ 7 | 8 | # lint files 9 | lint.xml 10 | 11 | # files for the dex VM 12 | *.dex 13 | 14 | # Java class files 15 | *.class 16 | 17 | # generated files 18 | bin/ 19 | out/ 20 | gen/ 21 | classes/ 22 | out/ 23 | gen-external-apklibs/ 24 | **/build 25 | 26 | # maven output folder 27 | target 28 | 29 | # Local configuration file (sdk path, etc) 30 | local.properties 31 | 32 | # Eclipse project files 33 | .classpath 34 | .project 35 | .metadata 36 | .settings 37 | 38 | # IntelliJ files 39 | .idea 40 | *.iml 41 | 42 | # OSX files 43 | .DS_Store 44 | 45 | # Windows files 46 | Thumbs.db 47 | 48 | # vi swap files 49 | *.swp 50 | 51 | # backup files 52 | *.bak 53 | 54 | # gradle directory 55 | .gradle -------------------------------------------------------------------------------- /Gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=1.02 2 | VERSION_CODE=1 3 | GROUP=com.github.amigold.fundapter2 4 | 5 | POM_NAME=FunDapter library 6 | POM_ARTIFACT_ID=library 7 | POM_PACKAGING=jar 8 | 9 | POM_DESCRIPTION=Simplify Adapter creation for your Android ListViews. 10 | POM_URL=https://github.com/amigold/FunDapter 11 | POM_SCM_URL=https://github.com/amigold/FunDapter 12 | POM_SCM_CONNECTION=scm:git@github.com:amigold/FunDapter.git 13 | POM_SCM_DEV_CONNECTION=scm:git@github.com:amigold/FunDapter.git 14 | POM_LICENCE_NAME=(The MIT License) 15 | POM_LICENCE_URL=http://opensource.org/licenses/MIT 16 | POM_LICENCE_DIST=repo 17 | POM_DEVELOPER_ID=amigold 18 | POM_DEVELOPER_NAME=Ami Goldenberg -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2012-2013 Ami Goldenberg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FunDapter takes the pain and hassle out of creating a new Adapter class for each ListView you have in your Android app. 2 | 3 | It is a new approach to custom adapter creation for Android apps. 4 | You get free ViewHolder pattern support, field validation so you don't get bit by trivial bugs and best of all - you get to keep it DRY! 5 | 6 | ## What's new? 7 | 8 | 1. Gradle support now only contains a JAR archive instead of AAR which wasn't needed. Just add `compile 'com.github.amigold.fundapter2:library:1.01'` to your dependencies in the build.gradle file in your project. 9 | 10 | ## What you used to do: 11 | 12 | 1. Subclass BaseAdapter or copy existing adapter you already wrote. 13 | 2. Create a ViewHolder static class a define all the views in it. 14 | 3. Write (Copy.. don't fool yourself!) the whole ViewHolder creation code from somewhere. 15 | 4. Write all the "findViewById" lines. 16 | 5. Start filling data in the views inside the getView method. 17 | 18 | Well that was boring! I feel your pain! 19 | 20 | ## What FunDapter lets you do: 21 | 22 | 1. Create a new BindDictionary 23 | 2. Add fields. 24 | 3. Create a new FunDapter instance, supplying the BindDictionary, layout resource file and item list. 25 | 26 | ## Getting Started 27 | 28 | This is the `Product` class we'll create an adapter for: 29 | 30 | ```java 31 | public class Product { 32 | 33 | public String title; 34 | public String description; 35 | public String imageUrl; 36 | public double price; 37 | } 38 | ``` 39 | 40 | ### Create a new BindDictionary instance: 41 | 42 | ```java 43 | BindDictionary dict = new BindDictionary(); 44 | ``` 45 | 46 | ### Adding a basic text field: 47 | 48 | ```java 49 | dict.addStringField(R.id.description, 50 | new StringExtractor() { 51 | 52 | @Override 53 | public String getStringValue(Product item, int position) { 54 | return item.description; 55 | } 56 | }); 57 | ``` 58 | 59 | Notice how you simply provide the id of the `TextView` and an 60 | implementation of the `StringExtractor` which will be used to get the correct `String` value from your `Product`. 61 | 62 | -------------------- 63 | ### Now a more complicated text field: 64 | 65 | ```java 66 | dict.addStringField(R.id.title, 67 | new StringExtractor() { 68 | 69 | @Override 70 | public String getStringValue(Product item, int position) { 71 | return item.title; 72 | } 73 | }).typeface(myBoldFace).visibilityIfNull(View.GONE); 74 | ``` 75 | 76 | Notice how you can chain calls to get some more complex behaviours out of your views. 77 | `typeface()` will set a typeface on the view while 78 | `visibilityIfNull()` will change the visibility of the field according to the value being null or not. 79 | 80 | -------------------- 81 | 82 | ### What about our image?? Lets add that as well: 83 | 84 | ```java 85 | prodDict.addDynamicImageField(R.id.productImage, 86 | new StringExtractor() { 87 | 88 | @Override 89 | public String getStringValue(Product item, int position) { 90 | return item.imageUrl; 91 | } 92 | }, new DynamicImageLoader() { 93 | @Override 94 | public void loadDynamicImage(String url, ImageView view) { 95 | //insert your own async image loader implementation 96 | } 97 | }); 98 | ``` 99 | 100 | In here the `StringExtractor` grabs the URL from the `Product` item while the `ImageLoader` gives you a 101 | reference to the view and the URL you extracted so you can use your own custom lazy image loading implementation. 102 | 103 | ------------- 104 | ### Finally, create the adapter: 105 | 106 | ```java 107 | FunDapter adapter = new FunDapter(getActivity(), productArrayList, 108 | R.layout.product_list_item, dict); 109 | ``` 110 | 111 | ## What is supported so far: 112 | 113 | * ViewHolder pattern and more performance optimizations 114 | * Switching data using `funDapter.updateData()` 115 | * Alternating background colors for the list items. Use `funDapter.setAlternatingBackground()` 116 | * Text fields: 117 | * typeface 118 | * visibility if null 119 | * changing textcolor based on a boolean condition - chain `conditionalTextColor()` when setting the field 120 | * Image fields (that load from the web) 121 | * ProgressBar fields - for showing user progress or xp. 122 | * Conditional visibility views - views that are shown or hidden according to some boolean value. (Good for decorations such as "sale" banners) 123 | * All fields support setting an OnClickListener by chaining `onClick()` 124 | * ExpandableListAdapter is supported 125 | 126 | ## What next? 127 | 128 | * Support for ViewPagerAdapter 129 | * Support for Favorite toggle buttons (where you provide your own implementation for the data persistence) 130 | * Whatever else I can think of! 131 | 132 | ## Gradle Support 133 | Just add `compile 'com.github.amigold.fundapter:library:1.0'` to your dependencies in the build.gradle file in your project. 134 | 135 | ## License 136 | 137 | (The MIT License) 138 | 139 | Copyright (c) 2012-2013 Ami Goldenberg 140 | 141 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 142 | 143 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 144 | 145 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 146 | -------------------------------------------------------------------------------- /Sample/.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Local configuration file (sdk path, etc) 17 | local.properties 18 | 19 | # Eclipse project files 20 | .classpath 21 | .project 22 | 23 | # IDEA Ignores 24 | *.iml 25 | *.ipr 26 | *.iws 27 | .idea/ 28 | local.properties 29 | 30 | # Generic Android ignores 31 | bin/ 32 | target 33 | gen/ -------------------------------------------------------------------------------- /Sample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 11 | 13 | 15 | 17 | 19 | 24 | 27 | 28 | 30 | 32 | 33 | 34 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Sample/assets/arialbd.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/assets/arialbd.ttf -------------------------------------------------------------------------------- /Sample/assets/categories.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Hats", 4 | "products": [ 5 | { 6 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 7 | "description": "pants you can wear and stuff", 8 | "title": "Hot pants!", 9 | "price": 259 10 | }, 11 | { 12 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 13 | "description": "good for the ladies", 14 | "title": "Android shirt", 15 | "price": 359 16 | }, 17 | { 18 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 19 | "description": "for the head!", 20 | "title": "Cool hat", 21 | "price": 159.9 22 | } 23 | ] 24 | }, 25 | { 26 | "title": "Pants", 27 | "products": [ 28 | { 29 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 30 | "description": "pants you can wear and stuff", 31 | "title": "Hot pants!", 32 | "price": 259 33 | }, 34 | { 35 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 36 | "description": "good for the ladies", 37 | "title": "Android shirt", 38 | "price": 359 39 | }, 40 | { 41 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 42 | "description": "for the head!", 43 | "title": "Cool hat", 44 | "price": 159.9 45 | } 46 | ] 47 | }, 48 | { 49 | "title": "Rollerblades", 50 | "products": [ 51 | { 52 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 53 | "description": "pants you can wear and stuff", 54 | "title": "Hot pants!", 55 | "price": 259 56 | }, 57 | { 58 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 59 | "description": "good for the ladies", 60 | "title": "Android shirt", 61 | "price": 359 62 | }, 63 | { 64 | "imageUrl": "http://proguard.sourceforge.net/android_shades.png", 65 | "description": "for the head!", 66 | "title": "Cool hat", 67 | "price": 159.9 68 | } 69 | ] 70 | } 71 | ] -------------------------------------------------------------------------------- /Sample/assets/products.json: -------------------------------------------------------------------------------- 1 | 2 | [{ 3 | "imageUrl" : "http://proguard.sourceforge.net/android_shades.png", 4 | "description" : "pants you can wear and stuff", 5 | "title" : "Hot pants!", 6 | "price" : 259 7 | }, { 8 | "imageUrl" : "http://proguard.sourceforge.net/android_shades.png", 9 | "description" : "good for the ladies", 10 | "title" : "Android shirt", 11 | "price" : 359 12 | }, { 13 | "imageUrl" : "http://proguard.sourceforge.net/android_shades.png", 14 | "description" : "for the head!", 15 | "title" : "Cool hat", 16 | "price" : 159.9 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /Sample/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:0.12.+' 7 | } 8 | } 9 | apply plugin: 'android' 10 | 11 | android { 12 | defaultConfig { 13 | versionCode 1 14 | versionName getVersionName() 15 | 16 | minSdkVersion 10 17 | targetSdkVersion 18 18 | } 19 | 20 | sourceSets { 21 | main { 22 | manifest.srcFile 'AndroidManifest.xml' 23 | java.srcDirs = ['src'] 24 | resources.srcDirs = ['src'] 25 | aidl.srcDirs = ['src'] 26 | renderscript.srcDirs = ['src'] 27 | res.srcDirs = ['res'] 28 | assets.srcDirs = ['assets'] 29 | } 30 | 31 | } 32 | compileSdkVersion 18 33 | buildToolsVersion "19.1.0" 34 | 35 | compileOptions { 36 | sourceCompatibility JavaVersion.VERSION_1_7 37 | targetCompatibility JavaVersion.VERSION_1_7 38 | } 39 | 40 | lintOptions { 41 | // set to true to turn off analysis progress reporting by lint 42 | quiet true 43 | // if true, stop the gradle build if errors are found 44 | abortOnError true 45 | // if true, only report errors 46 | ignoreWarnings false 47 | // if true, check all issues, including those that are off by default 48 | checkAllWarnings true 49 | // if true, treat all warnings as errors 50 | warningsAsErrors true 51 | // turn off checking the given issue id's 52 | // disable 'TypographyFractions','TypographyQuotes' 53 | // turn on the given issue id's 54 | // enable 'RtlHardcoded','RtlCompat', 'RtlEnabled' 55 | // check *only* the given issue id's 56 | // check 'NewApi', 'InlinedApi' 57 | // if true, don't include source code lines in the error output 58 | noLines false 59 | // if true, show all locations for an error, do not truncate lists, etc. 60 | showAll true 61 | // if true, generate a text report of issues (false by default) 62 | textReport true 63 | // location to write the output; can be a file or 'stdout' 64 | textOutput 'stdout' 65 | // if true, generate an XML report for use by for example Jenkins 66 | xmlReport false 67 | // file to write report to (if not specified, defaults to lint-results.xml) 68 | xmlOutput file("build/lint/lint-results.xml") 69 | // if true, generate an HTML report (with issue explanations, sourcecode, etc) 70 | htmlReport true 71 | htmlOutput file("build/lint/lint-results.html") 72 | 73 | } 74 | } 75 | 76 | repositories { 77 | mavenCentral() 78 | } 79 | 80 | 81 | dependencies { 82 | compile project(':library') 83 | compile 'com.google.code.gson:gson:2.2.+' 84 | } 85 | -------------------------------------------------------------------------------- /Sample/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/libs/android-support-v4.jar -------------------------------------------------------------------------------- /Sample/libs/gson-2.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/libs/gson-2.2.2.jar -------------------------------------------------------------------------------- /Sample/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /Sample/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | android.library.reference.1=../library 16 | -------------------------------------------------------------------------------- /Sample/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Sample/res/drawable-hdpi/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/res/drawable-hdpi/placeholder.png -------------------------------------------------------------------------------- /Sample/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Sample/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amigold/FunDapter/fb33241f265901d73276608689077d4310278eaf/Sample/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Sample/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 15 |