├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── dbnavigator.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── francoisdexemple │ │ └── materialpreferencedemo │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── com │ │ │ └── francoisdexemple │ │ │ └── materialpreferencedemo │ │ │ ├── Application.java │ │ │ ├── Demo.java │ │ │ ├── ExampleMaterialPreferenceActivity.java │ │ │ ├── ExampleMaterialPreferenceFragment.java │ │ │ ├── ExampleMaterialPreferenceFragmentActivity.java │ │ │ ├── ExampleMaterialPreferenceLicenseActivity.java │ │ │ ├── MainActivity.java │ │ │ └── custom │ │ │ ├── MyCustomItem.java │ │ │ └── MyViewTypeManager.java │ ├── res │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ │ ├── activity_example_material_preference_fragment.xml │ │ │ ├── activity_main.xml │ │ │ ├── content_example_material_preference_fragment.xml │ │ │ ├── content_main.xml │ │ │ ├── custom_item.xml │ │ │ ├── mp_material_preference_action_item_overridefornoicons.xml │ │ │ └── mp_material_preference_list_card_overrideforlistlayout.xml │ │ ├── menu │ │ │ ├── menu_example_material_preference.xml │ │ │ └── menu_main.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── xml │ │ │ └── backup_descriptor.xml │ └── web_hi_res_512.png │ └── test │ └── java │ └── com │ └── francoisdexemple │ └── materialpreferencedemo │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── materialpreference ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── francoisdexemple │ │ └── materialpreference │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── francoisdexemple │ │ │ └── materialpreference │ │ │ ├── ConvenienceBuilder.java │ │ │ ├── MaterialPreferenceActivity.java │ │ │ ├── MaterialPreferenceFragment.java │ │ │ ├── adapters │ │ │ ├── MaterialPreferenceItemAdapter.java │ │ │ └── MaterialPreferenceListAdapter.java │ │ │ ├── holders │ │ │ └── MaterialPreferenceItemViewHolder.java │ │ │ ├── items │ │ │ ├── MaterialPreferenceActionItem.java │ │ │ ├── MaterialPreferenceCheckBoxItem.java │ │ │ ├── MaterialPreferenceItem.java │ │ │ ├── MaterialPreferenceItemOnClickAction.java │ │ │ ├── MaterialPreferenceOnCheckedChangedListener.java │ │ │ ├── MaterialPreferenceSwitchItem.java │ │ │ └── MaterialPreferenceTitleItem.java │ │ │ ├── model │ │ │ ├── MaterialPreferenceCard.java │ │ │ └── MaterialPreferenceList.java │ │ │ └── util │ │ │ ├── DefaultViewTypeManager.java │ │ │ ├── OpenSourceLicense.java │ │ │ └── ViewTypeManager.java │ └── res │ │ ├── layout │ │ ├── material_preference_action_item.xml │ │ ├── material_preference_activity.xml │ │ ├── material_preference_checkbox_item.xml │ │ ├── material_preference_fragment.xml │ │ ├── material_preference_list_card.xml │ │ ├── material_preference_switch_item.xml │ │ └── material_preference_title_item.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── francoisdexemple │ └── materialpreference │ └── ExampleUnitTest.java ├── screenshots ├── 1.png ├── 2.png ├── 2_mini.png ├── 3.png ├── 4.png ├── 5.png └── 6.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | 12 | 13 | # Created by https://www.gitignore.io/api/android,windows,androidstudio 14 | 15 | ### Android ### 16 | # Built application files 17 | *.apk 18 | *.ap_ 19 | 20 | # Files for the ART/Dalvik VM 21 | *.dex 22 | 23 | # Java class files 24 | *.class 25 | 26 | # Generated files 27 | bin/ 28 | gen/ 29 | out/ 30 | 31 | # Gradle files 32 | .gradle/ 33 | build/ 34 | 35 | # Local configuration file (sdk path, etc) 36 | local.properties 37 | 38 | # Proguard folder generated by Eclipse 39 | proguard/ 40 | 41 | # Log Files 42 | *.log 43 | 44 | # Android Studio Navigation editor temp files 45 | .navigation/ 46 | 47 | # Android Studio captures folder 48 | captures/ 49 | 50 | # Intellij 51 | *.iml 52 | .idea/workspace.xml 53 | .idea/tasks.xml 54 | .idea/gradle.xml 55 | .idea/dictionaries 56 | .idea/libraries 57 | 58 | # External native build folder generated in Android Studio 2.2 and later 59 | .externalNativeBuild 60 | 61 | # Freeline 62 | freeline.py 63 | freeline/ 64 | freeline_project_description.json 65 | 66 | ### Android Patch ### 67 | gen-external-apklibs 68 | 69 | ### AndroidStudio ### 70 | # Covers files to be ignored for android development using Android Studio. 71 | 72 | # Built application files 73 | 74 | # Files for the ART/Dalvik VM 75 | 76 | # Java class files 77 | 78 | # Generated files 79 | 80 | # Gradle files 81 | .gradle 82 | 83 | # Signing files 84 | .signing/ 85 | 86 | # Local configuration file (sdk path, etc) 87 | 88 | # Proguard folder generated by Eclipse 89 | 90 | # Log Files 91 | 92 | # Android Studio 93 | /*/build/ 94 | /*/local.properties 95 | /*/out 96 | /*/*/build 97 | /*/*/production 98 | *.ipr 99 | *~ 100 | *.swp 101 | 102 | # Android Patch 103 | 104 | # External native build folder generated in Android Studio 2.2 and later 105 | 106 | # NDK 107 | obj/ 108 | 109 | # IntelliJ IDEA 110 | *.iws 111 | /out/ 112 | 113 | # User-specific configurations 114 | .idea/caches/ 115 | .idea/libraries/ 116 | .idea/shelf/ 117 | .idea/.name 118 | .idea/compiler.xml 119 | .idea/copyright/profiles_settings.xml 120 | .idea/encodings.xml 121 | .idea/misc.xml 122 | .idea/modules.xml 123 | .idea/scopes/scope_settings.xml 124 | .idea/vcs.xml 125 | .idea/jsLibraryMappings.xml 126 | .idea/datasources.xml 127 | .idea/dataSources.ids 128 | .idea/sqlDataSources.xml 129 | .idea/dynamic.xml 130 | .idea/uiDesigner.xml 131 | 132 | # OS-specific files 133 | .DS_Store 134 | .DS_Store? 135 | ._* 136 | .Spotlight-V100 137 | .Trashes 138 | ehthumbs.db 139 | Thumbs.db 140 | 141 | # Legacy Eclipse project files 142 | .classpath 143 | .project 144 | .cproject 145 | .settings/ 146 | 147 | # Mobile Tools for Java (J2ME) 148 | .mtj.tmp/ 149 | 150 | # Package Files # 151 | *.war 152 | *.ear 153 | 154 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) 155 | hs_err_pid* 156 | 157 | ## Plugin-specific files: 158 | 159 | # mpeltonen/sbt-idea plugin 160 | .idea_modules/ 161 | 162 | # JIRA plugin 163 | atlassian-ide-plugin.xml 164 | 165 | # Mongo Explorer plugin 166 | .idea/mongoSettings.xml 167 | 168 | # Crashlytics plugin (for Android Studio and IntelliJ) 169 | com_crashlytics_export_strings.xml 170 | crashlytics.properties 171 | crashlytics-build.properties 172 | fabric.properties 173 | 174 | ### AndroidStudio Patch ### 175 | 176 | !/gradle/wrapper/gradle-wrapper.jar 177 | 178 | ### Windows ### 179 | # Windows thumbnail cache files 180 | ehthumbs_vista.db 181 | 182 | # Folder config file 183 | Desktop.ini 184 | 185 | # Recycle Bin used on file shares 186 | $RECYCLE.BIN/ 187 | 188 | # Windows Installer files 189 | *.cab 190 | *.msi 191 | *.msm 192 | *.msp 193 | 194 | # Windows shortcuts 195 | *.lnk 196 | 197 | 198 | # End of https://www.gitignore.io/api/android,windows,androidstudio -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 26 | 27 | 28 | 29 | 39 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 62 | 63 | 64 | 70 | 71 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # material-preference-library : DEPRECATED PLEASE LOOK HERE FOR THE SAME THING [material-about-library from daniel-stoneuk][6] 2 | 3 | Makes it easy to create a beautiful preference screen for your app. Generates an `Activity` or `Fragment`. 4 | 5 | Fork from here: [material-about-library from daniel-stoneuk][6] 6 | 7 | If you use this library in your app, please let me know and I'll add it to the list. 8 | 9 | 10 | ## Screenshots 11 | 12 | | Light with Light Action Bar | Light with Dark Action Bar | Dark with Light Action Bar | Dark with Dark Action Bar | Custom Cardview Background | Custom card & action item layout | 13 | | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | 14 | | ![Demo App](screenshots/1.png) | ![Demo App](screenshots/2.png) | ![Demo App](screenshots/3.png) | ![Demo App](screenshots/4.png) | ![Demo App](screenshots/5.png) | ![Demo App](screenshots/6.png) | 15 | 16 | ## Features 17 | 18 | - Material design 19 | - Modular backend 20 | - Easy to implement 21 | - Simple but intuitive API 22 | - Dynamic item support 23 | - Support Switch and Checkbox (more after) 24 | 25 | ## Dependency 26 | 27 | _material-preference-library_ is available on [**jitpack.io**][1] and has support for different support library versions. See the full list [here](https://jitpack.io/#filol/material-preference-library). 28 | 29 | **Gradle dependency:** 30 | 31 | ```gradle 32 | allprojects { 33 | repositories { 34 | maven { url 'https://jitpack.io' } 35 | } 36 | } 37 | ``` 38 | 39 | ```gradle 40 | dependencies { 41 | implementation 'com.github.filol:material-preference-library:1.0' 42 | } 43 | ``` 44 | 45 | ## Setup 46 | 47 | ### Activity 48 | 49 | Your `Activity` must extend [`MaterialPreferenceActivity`][materialpreferenceactivityjava] and be in your _AndroidManifest.xml_: 50 | 51 | ```java 52 | public class ExampleMaterialPreferenceActivity extends MaterialPreferenceActivity { 53 | 54 | @Override 55 | @NonNull 56 | protected MaterialPreferenceList getMaterialPreferenceList(@NonNull Context context) { 57 | return new MaterialPreferenceList.Builder() 58 | .build(); // This creates an empty screen, add cards with .addCard() 59 | } 60 | 61 | @Override 62 | protected CharSequence getActivityTitle() { 63 | return getString(R.string.mp_title_preference); 64 | } 65 | 66 | } 67 | ``` 68 | 69 | Ensure that the theme extends either of these themes, and apply primary & accent colours: 70 | 71 | - `Theme.mp.Light` (light theme with light toolbar) 72 | - `Theme.mp.Light.DarkActionBar` (light theme with dark toolbar) 73 | - `Theme.mp.Dark` (dark theme with dark toolbar) 74 | - `Theme.mp.Dark.LightActionBar` (dark theme with light toolbar) 75 | 76 | ```xml 77 | 78 | 79 | 81 | 82 | 83 | ``` 84 | 85 | ```xml 86 | 91 | ``` 92 | 93 | ### Fragment 94 | 95 | Your `Fragment` must extend [`MaterialPreferenceFragment`][materialpreferencefragmentjava]. 96 | 97 | ```java 98 | public class ExampleMaterialPreferenceFragment extends MaterialPreferenceFragment { 99 | 100 | @Override 101 | protected MaterialPreferenceList getMaterialPreferenceList(final Context activityContext) { 102 | return new MaterialPreferenceList.Builder() 103 | .build(); // This creates an empty screen, add cards with .addCard() 104 | } 105 | 106 | @Override 107 | protected int getTheme() { 108 | return R.style.AppTheme_MaterialPreferenceActivity_Fragment; 109 | } 110 | 111 | } 112 | ``` 113 | 114 | Pass in a theme that extends one of the styles above 115 | 116 | ```xml 117 | 122 | ``` 123 | 124 | ### Add Cards: 125 | 126 | Start building a "card" using [`MaterialPreferenceCard.Builder()`][8] 127 | 128 | ```java 129 | public class ExampleMaterialPreferenceActivity extends MaterialPreferenceActivity { 130 | 131 | @Override 132 | @NonNull 133 | protected MaterialPreferenceList getMaterialPreferenceList(@NonNull Context context) { 134 | MaterialPreferenceCard card = new MaterialPreferenceCard.Builder() 135 | // Configure card here 136 | .build(); 137 | 138 | return new MaterialPreferenceList.Builder() 139 | .addCard(card) 140 | .build(); 141 | } 142 | } 143 | ``` 144 | 145 | Give the card a title by calling `.title()` on the `MaterialPreferenceCard.Builder` 146 | 147 | ```java 148 | MaterialPreferenceCard card = new MaterialPreferenceCard.Builder() 149 | .title("Author") 150 | .build(); 151 | ``` 152 | 153 | ### Add Items to a card: 154 | 155 | There are currently 4 types of items you can add to a card - [`MaterialPreferenceTitleItem`][9], [`MaterialPreferenceActionItem`][10], [`MaterialPreferenceCheckboxItem`][12] and [`MaterialPreferenceSwitchItem`][13]. Other types of items are planned, for example "person" items which feature buttons to showcase a single person. Feel free to submit a PR or Issue for more item ideas. 156 | 157 | - `MaterialPreferenceActionItem`: Standard item with text, icon and optional subtext. 158 | - `MaterialPreferenceTitleItem`: Larger item with large icon (e.g. app icon) and larger text. 159 | 160 | [`MaterialPreferenceTitleItem`][9] is created with [`MaterialPreferenceTitleItem.Builder()`][9] and lets you specify **text** and an **icon**. 161 | 162 | ```java 163 | MaterialPreferenceCard.Builder cardBuilder = new MaterialPreferenceCard.Builder(); 164 | cardBuilder.addItem(new MaterialPreferenceTitleItem.Builder() 165 | .text("Material Preference Library") 166 | .icon(R.mipmap.ic_launcher) 167 | .build()); 168 | ``` 169 | 170 | [`MaterialPreferenceItem`][10] is created with [`MaterialPreferenceItem.Builder()`][10] and lets you specify **text**, **sub-text**, an **icon** and an **OnClickAction**. 171 | 172 | ```java 173 | cardBuilder.addItem(new MaterialPreferenceActionItem.Builder() 174 | .text("Version") 175 | .subText("1.0.0") 176 | .icon(R.drawable.ic_about_info) 177 | .setOnClickAction(new MaterialPreferenceActionItem.OnClickAction() { 178 | @Override 179 | public void onClick() { 180 | Toast.makeText(ExampleMaterialPreferenceActivity.this, "Version Tapped", Toast.LENGTH_SHORT) 181 | .show(); 182 | } 183 | }) 184 | .build()); 185 | ``` 186 | 187 | [`MaterialPreferenceCheckboxItem`][12] is created with [`MaterialPreferenceCheckboxItem.Builder()`][12] and lets you specify **text**, **sub-text**, an **icon** and an **onCheckedChangedListener**. 188 | 189 | ```java 190 | cardBuilder.addItem(new MaterialPreferenceCheckboxItem.Builder() 191 | .text("Activate something") 192 | .subText("desciption") 193 | .icon(R.drawable.ic_about_info) 194 | .setOnCheckedChanged(new MaterialPreferenceOnCheckedChangedListener() { 195 | @Override 196 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 197 | Toast.makeText(c,"Now : "+isChecked,Toast.LENGTH_SHORT).show(); 198 | } 199 | }) 200 | .build()); 201 | ``` 202 | 203 | 204 | [`MaterialPreferenceSwitchItem`][10] is created with [`MaterialPreferenceSwitchItem.Builder()`][10] and lets you specify **text**, **sub-text**, an **icon** and an **onCheckedChangedListener**. 205 | 206 | ```java 207 | cardBuilder.addItem(new MaterialPreferenceSwitchItem.Builder() 208 | .text("Version") 209 | .subText("1.0.0") 210 | .icon(R.drawable.ic_about_info) 211 | .setOnCheckedChanged(new MaterialPreferenceOnCheckedChangedListener() { 212 | @Override 213 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 214 | Toast.makeText(c,"Now : "+isChecked,Toast.LENGTH_SHORT).show(); 215 | } 216 | }) 217 | .build()); 218 | ``` 219 | 220 | ### Return the list: 221 | 222 | Create a [`MaterialPreferenceList`][11] using [`MaterialPreferenceList.Builder()`][11], passing in the cards you would like to display. 223 | 224 | ```java 225 | MaterialPreferenceCard card = new MaterialPreferenceCard.Builder() 226 | .title("Hey! I'm a card") 227 | .build(); 228 | 229 | return new MaterialPreferenceList.Builder() 230 | .addCard(card) 231 | .build(); 232 | ``` 233 | 234 | Check out a working example in [`Demo.java`][3]. 235 | 236 | **Tip:** You can either use _Strings_ / _Drawables_ or _Resources_ when creating `MaterialPreferenceItem`'s 237 | 238 | **Tip:** Use [Android-Iconics][iconics] for icons. "Android-Iconics - Use any icon font, or vector (.svg) as drawable in your application." 239 | 240 | **Tip:** Use [ConvenienceBuilder][conveniencebuilderjava] to easily create items or OnClickActions. 241 | 242 | **Tip:** Customise text colour and card colour in your styles. Example below: 243 | 244 | ```xml 245 | 259 | ``` 260 | 261 | ### Dynamic items: 262 | It's possible to create dynamic items that either change on tap (or when any other event occurs). There are two examples in the sample application. Simply change the items in the list variable and then call `refreshMaterialPreferenceList()`. DiffUtil calculates the changes to animate in the RecyclerView. 263 | 264 | ```java 265 | final MaterialPreferenceActionItem item = new MaterialPreferenceActionItem.Builder() 266 | .text("Dynamic UI") 267 | .subText(subText) 268 | .icon(new IconicsDrawable(c) 269 | .icon(CommunityMaterial.Icon.cmd_refresh) 270 | .color(ContextCompat.getColor(c, R.color.mp_color_icon_dark_theme) 271 | ).sizeDp(18)) 272 | .build(); 273 | item.setOnClickAction(new MaterialPreferenceItemOnClickAction() { 274 | @Override 275 | public void onClick() { 276 | item.setSubText("Random number: " + ((int) (Math.random() * 10))); 277 | refreshMaterialPreferenceList(); 278 | } 279 | }); 280 | ``` 281 | 282 | ### Custom card and Action layout 283 | To get a layout that is similar to the 6th screenshot above simply override the files `mp_material_preference_action_item` and `mp_material_preference_list_card` by creating new layout resources with the same filename. See [here](https://github.com/filol/material-preference-library/tree/master/materialpreference/src/main/res/layout). 284 | 285 | ## Contributors 286 | 287 | ### This Library 288 | - François Dexemple ([@filol](https://github.com/filol)) 289 | 290 | ### Original Library 291 | - Daniel Stone ([@daniel-stoneuk](https://github.com/daniel-stoneuk)) 292 | - Robert Pösel ([@Robyer](https://github.com/Robyer)) 293 | - Jonas Uekötter ([@ueman](https://github.com/ueman)) 294 | - Rainer Lang ([@Rainer-Lang](https://github.com/rainer-lang)) 295 | - Sebastian Guillen ([@code-schreiber](https://github.com/code-schreiber)) 296 | - and [others](https://github.com/daniel-stoneuk/material-about-library/graphs/contributors) 297 | 298 | ## License 299 | 300 | ``` 301 | Copyright 2016-2018 François Dexemple 302 | 303 | Licensed under the Apache License, Version 2.0 (the "License"); 304 | you may not use this file except in compliance with the License. 305 | You may obtain a copy of the License at 306 | 307 | http://www.apache.org/licenses/LICENSE-2.0 308 | 309 | Unless required by applicable law or agreed to in writing, software 310 | distributed under the License is distributed on an "AS IS" BASIS, 311 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 312 | See the License for the specific language governing permissions and 313 | limitations under the License. 314 | ``` 315 | 316 | [1]: https://jitpack.io 317 | [2]: http://i.imgur.com/xXWDmLb.png 318 | [3]: https://github.com/filol/material-preference-library/blob/master/app/src/main/java/com/francoisdexemple/materialpreferencedemo/Demo.java 319 | [4]: http://i.imgur.com/HEm08Ax.png 320 | [5]: https://play.google.com/store/apps/details?id=com.danielstone.energyhive 321 | [6]: https://github.com/daniel-stoneuk/material-about-library 322 | [8]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/model/MaterialPreferenceCard.java 323 | [9]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/items/MaterialPreferenceTitleItem.java 324 | [10]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/items/MaterialPreferenceActionItem.java 325 | [11]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/model/MaterialPreferenceList.java 326 | [12]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/items/MaterialPreferenceCheckBoxItem.java 327 | [13]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/items/MaterialPreferenceSwitchItem.java 328 | [conveniencebuilderjava]: https://github.com/filol/material-preference-library/blob/master/materialpreference/src/main/java/com/francoisdexemple/materialpreference/ConvenienceBuilder.java 329 | [iconics]: https://github.com/mikepenz/Android-Iconics 330 | [materialpreferenceactivityjava]: https://github.com/filol/material-preference-library/blob/master/app/src/main/java/com/francoisdexemple/materialpreferencedemo/ExampleMaterialPreferenceActivity.java 331 | [materialpreferencefragmentjava]: https://github.com/filol/material-preference-library/blob/master/app/src/main/java/com/francoisdexemple/materialpreferencedemo/ExampleMaterialPreferenceFragment.java 332 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "com.francoisdexemple.materialpreferencedemo" 7 | minSdkVersion 19 8 | targetSdkVersion 27 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'com.android.support:appcompat-v7:27.1.1' 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.0' 25 | testImplementation 'junit:junit:4.12' 26 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 28 | implementation project(':materialpreference') 29 | 30 | implementation "com.android.support:appcompat-v7:$supportLibVersion" 31 | implementation "com.android.support:design:$supportLibVersion" 32 | implementation "com.mikepenz:iconics-core:2.9.5@aar" 33 | implementation 'com.mikepenz:community-material-typeface:2.0.46.1@aar' 34 | 35 | debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakCanaryVersion" 36 | releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$leakCanaryVersion" 37 | testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$leakCanaryVersion" 38 | } 39 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/francoisdexemple/materialpreferencedemo/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.francoisdexemple.materialpreferencedemo", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filol/material-preference-library/335bdb2a3731a2becaf95f2a35259e6a23458b22/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/Application.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | 3 | import com.squareup.leakcanary.LeakCanary; 4 | 5 | public class Application extends android.app.Application { 6 | 7 | @Override public void onCreate() { 8 | super.onCreate(); 9 | if (LeakCanary.isInAnalyzerProcess(this)) { 10 | // This process is dedicated to LeakCanary for heap analysis. 11 | // You should not init your app in this process. 12 | return; 13 | } 14 | LeakCanary.install(this); 15 | // Normal app init code... 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/ExampleMaterialPreferenceActivity.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | import android.content.Context; 3 | import android.net.Uri; 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | import android.support.design.widget.Snackbar; 8 | import android.support.v4.content.ContextCompat; 9 | import android.util.Log; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | import android.widget.Toast; 13 | 14 | import com.francoisdexemple.materialpreference.ConvenienceBuilder; 15 | import com.francoisdexemple.materialpreference.MaterialPreferenceActivity; 16 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceActionItem; 17 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceItemOnClickAction; 18 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceTitleItem; 19 | import com.francoisdexemple.materialpreference.model.MaterialPreferenceCard; 20 | import com.francoisdexemple.materialpreference.model.MaterialPreferenceList; 21 | import com.francoisdexemple.materialpreference.util.ViewTypeManager; 22 | import com.francoisdexemple.materialpreferencedemo.custom.MyCustomItem; 23 | import com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager; 24 | import com.mikepenz.community_material_typeface_library.CommunityMaterial; 25 | import com.mikepenz.iconics.IconicsDrawable; 26 | 27 | public class ExampleMaterialPreferenceActivity extends MaterialPreferenceActivity { 28 | 29 | public static final String THEME_EXTRA = ""; 30 | public static final int THEME_LIGHT_LIGHTBAR = 0; 31 | public static final int THEME_LIGHT_DARKBAR = 1; 32 | public static final int THEME_DARK_LIGHTBAR = 2; 33 | public static final int THEME_DARK_DARKBAR = 3; 34 | public static final int THEME_CUSTOM_CARDVIEW = 4; 35 | 36 | protected int colorIcon = R.color.mp_color_icon_light_theme; 37 | 38 | @NonNull 39 | @Override 40 | protected MaterialPreferenceList getMaterialPreferenceList(@NonNull final Context c) { 41 | MaterialPreferenceCard.Builder advancedCardBuilder = new MaterialPreferenceCard.Builder(); 42 | advancedCardBuilder.title("Advanced"); 43 | 44 | advancedCardBuilder.addItem(new MaterialPreferenceTitleItem.Builder() 45 | .text("TitleItem OnClickAction") 46 | .icon(R.mipmap.ic_launcher) 47 | .setOnClickAction(ConvenienceBuilder.createWebsiteOnClickAction(c, Uri.parse("http://www.daniel-stone.uk"))) 48 | .build()); 49 | 50 | advancedCardBuilder.addItem(new MaterialPreferenceActionItem.Builder() 51 | .text("Snackbar demo") 52 | .icon(new IconicsDrawable(c) 53 | .icon(CommunityMaterial.Icon.cmd_code_tags) 54 | .color(ContextCompat.getColor(c, colorIcon)) 55 | .sizeDp(18)) 56 | .setOnClickAction(new MaterialPreferenceItemOnClickAction() { 57 | @Override 58 | public void onClick() { 59 | Snackbar.make(((ExampleMaterialPreferenceActivity) c).findViewById(R.id.mp_material_preference_activity_coordinator_layout), "Test", Snackbar.LENGTH_SHORT).show(); 60 | } 61 | }) 62 | .build()); 63 | 64 | advancedCardBuilder.addItem(new MaterialPreferenceActionItem.Builder() 65 | .text("OnLongClickAction demo") 66 | .icon(new IconicsDrawable(c) 67 | .icon(CommunityMaterial.Icon.cmd_hand_pointing_right) 68 | .color(ContextCompat.getColor(c, colorIcon)) 69 | .sizeDp(18)) 70 | .setOnLongClickAction(new MaterialPreferenceItemOnClickAction() { 71 | @Override 72 | public void onClick() { 73 | Toast.makeText(c, "Long pressed", Toast.LENGTH_SHORT).show(); 74 | } 75 | }) 76 | .build()); 77 | 78 | advancedCardBuilder.addItem(new MyCustomItem.Builder() 79 | .text("Custom Item") 80 | .icon(new IconicsDrawable(c) 81 | .icon(CommunityMaterial.Icon.cmd_code_braces) 82 | .color(ContextCompat.getColor(c, colorIcon)) 83 | .sizeDp(18)) 84 | .build()); 85 | 86 | advancedCardBuilder.addItem(createDynamicItem("Tap for a random number & swap position", c)); 87 | 88 | return Demo.createMaterialPreferenceList(c, colorIcon, getIntent().getIntExtra(THEME_EXTRA, THEME_LIGHT_DARKBAR)).addCard(advancedCardBuilder.build()); 89 | } 90 | 91 | private MaterialPreferenceActionItem createDynamicItem(String subText, final Context c) { 92 | final MaterialPreferenceActionItem item = new MaterialPreferenceActionItem.Builder() 93 | .text("Dynamic UI") 94 | .subText(subText) 95 | .icon(new IconicsDrawable(c) 96 | .icon(CommunityMaterial.Icon.cmd_refresh) 97 | .color(ContextCompat.getColor(c, colorIcon) 98 | ).sizeDp(18)) 99 | .build(); 100 | item.setOnClickAction(new MaterialPreferenceItemOnClickAction() { 101 | @Override 102 | public void onClick() { 103 | getList().getCards().get(4).getItems().remove(getList().getCards().get(4).getItems().indexOf(item)); 104 | int newIndex = ((int) (Math.random() * 5)); 105 | getList().getCards().get(4).getItems().add(newIndex, item); 106 | item.setSubText("Random number: " + ((int) (Math.random() * 10))); 107 | setMaterialPreferenceList(getList()); 108 | } 109 | }); 110 | 111 | return item; 112 | } 113 | 114 | 115 | @Override 116 | protected void onCreate(@Nullable Bundle savedInstanceState) { 117 | Log.i("test", "onCreate: " + getIntent().getIntExtra(THEME_EXTRA, THEME_LIGHT_DARKBAR)); 118 | switch (getIntent().getIntExtra(THEME_EXTRA, THEME_LIGHT_DARKBAR)) { 119 | case THEME_LIGHT_LIGHTBAR: 120 | setTheme(R.style.AppTheme_MaterialPreferenceActivity_Light); 121 | colorIcon = R.color.mp_color_icon_light_theme; 122 | break; 123 | case THEME_DARK_LIGHTBAR: 124 | setTheme(R.style.AppTheme_MaterialPreferenceActivity_Dark_LightActionBar); 125 | colorIcon = R.color.mp_color_icon_dark_theme; 126 | break; 127 | case THEME_LIGHT_DARKBAR: 128 | setTheme(R.style.AppTheme_MaterialPreferenceActivity_Light_DarkActionBar); 129 | colorIcon = R.color.mp_color_icon_light_theme; 130 | break; 131 | case THEME_DARK_DARKBAR: 132 | setTheme(R.style.AppTheme_MaterialPreferenceActivity_Dark); 133 | colorIcon = R.color.mp_color_icon_dark_theme; 134 | break; 135 | case THEME_CUSTOM_CARDVIEW: 136 | setTheme(R.style.AppTheme_MaterialPreferenceActivity_Light_DarkActionBar_CustomCardView); 137 | colorIcon = R.color.mp_color_icon_dark_theme; 138 | break; 139 | } 140 | 141 | super.onCreate(savedInstanceState); 142 | 143 | // Call this method to let the scrollbar scroll off screen 144 | // setScrollToolbar(true); 145 | } 146 | 147 | @Override 148 | protected CharSequence getActivityTitle() { 149 | return getString(R.string.mp_title_preference); 150 | } 151 | 152 | @NonNull 153 | @Override 154 | protected ViewTypeManager getViewTypeManager() { 155 | return new MyViewTypeManager(); 156 | } 157 | 158 | @Override 159 | public boolean onCreateOptionsMenu(Menu menu) { 160 | super.onCreateOptionsMenu(menu); 161 | getMenuInflater().inflate(R.menu.menu_example_material_preference, menu); 162 | return true; 163 | } 164 | 165 | @Override 166 | public boolean onOptionsItemSelected(MenuItem item) { 167 | if (item.getItemId() == R.id.action_refresh) { 168 | refreshMaterialPreferenceList(); 169 | return true; 170 | } 171 | return super.onOptionsItemSelected(item); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/ExampleMaterialPreferenceFragment.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | import android.content.Context; 3 | import android.os.Handler; 4 | import android.support.v4.content.ContextCompat; 5 | import android.util.Log; 6 | 7 | 8 | import com.francoisdexemple.materialpreference.MaterialPreferenceFragment; 9 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceActionItem; 10 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceItemOnClickAction; 11 | import com.francoisdexemple.materialpreference.model.MaterialPreferenceList; 12 | import com.mikepenz.community_material_typeface_library.CommunityMaterial; 13 | import com.mikepenz.iconics.IconicsDrawable; 14 | 15 | import static com.francoisdexemple.materialpreferencedemo.ExampleMaterialPreferenceActivity.THEME_LIGHT_DARKBAR; 16 | 17 | 18 | public class ExampleMaterialPreferenceFragment extends MaterialPreferenceFragment { 19 | 20 | private MaterialPreferenceActionItem createDynamicItem(String subText, final Context c) { 21 | final MaterialPreferenceActionItem item = new MaterialPreferenceActionItem.Builder() 22 | .text("Dynamic UI") 23 | .subText(subText) 24 | .icon(new IconicsDrawable(c) 25 | .icon(CommunityMaterial.Icon.cmd_refresh) 26 | .color(ContextCompat.getColor(c, R.color.mp_color_icon_dark_theme) 27 | ).sizeDp(18)) 28 | .build(); 29 | item.setOnClickAction(new MaterialPreferenceItemOnClickAction() { 30 | @Override 31 | public void onClick() { 32 | item.setSubText("Random number: " + ((int) (Math.random() * 10))); 33 | refreshMaterialPreferenceList(); 34 | } 35 | }); 36 | return item; 37 | 38 | } 39 | 40 | @Override 41 | protected MaterialPreferenceList getMaterialPreferenceList(final Context c) { 42 | MaterialPreferenceList list = Demo.createMaterialPreferenceList(c, R.color.mp_color_icon_dark_theme, THEME_LIGHT_DARKBAR); 43 | 44 | list.getCards().get(2).getItems().add(createDynamicItem("Tap for a random number", c)); 45 | 46 | final MaterialPreferenceActionItem time = new MaterialPreferenceActionItem.Builder() 47 | .text("Unix Time In Millis") 48 | .subText("Time") 49 | .icon(new IconicsDrawable(c) 50 | .icon(CommunityMaterial.Icon.cmd_clock) 51 | .color(ContextCompat.getColor(c, R.color.mp_color_icon_dark_theme) 52 | ).sizeDp(18)) 53 | .build(); 54 | list.getCards().get(2).getItems().add(time); 55 | 56 | return list; 57 | } 58 | 59 | final Handler handler = new Handler(); 60 | Runnable runnable = new Runnable() { 61 | @Override 62 | public void run() { 63 | Log.i("MaterialPrefFragment", "Updating with time"); 64 | if (getList().getCards().size() > 0) { 65 | ((MaterialPreferenceActionItem) getList().getCards().get(2).getItems().get(7)).setSubText("" + System.currentTimeMillis()); 66 | refreshMaterialPreferenceList(); 67 | } 68 | handler.postDelayed(this, 1000); 69 | } 70 | }; 71 | 72 | 73 | @Override 74 | public void onResume() { 75 | super.onResume(); 76 | runnable.run(); 77 | } 78 | 79 | @Override 80 | public void onPause() { 81 | super.onPause(); 82 | handler.removeCallbacks(runnable); 83 | } 84 | 85 | @Override 86 | protected int getTheme() { 87 | return R.style.AppTheme_MaterialPreferenceActivity_Fragment; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/ExampleMaterialPreferenceFragmentActivity.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.NavUtils; 5 | import android.support.v7.app.ActionBar; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.support.v7.widget.Toolbar; 8 | 9 | public class ExampleMaterialPreferenceFragmentActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_example_material_preference_fragment); 15 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 16 | setSupportActionBar(toolbar); 17 | getSupportFragmentManager().beginTransaction() 18 | .replace(R.id.container, ExampleMaterialPreferenceFragment.newInstance(new ExampleMaterialPreferenceFragment())) 19 | .commit(); 20 | 21 | setTitle("Preference Fragment Activity"); 22 | 23 | if (NavUtils.getParentActivityName(this) != null) { 24 | ActionBar actionBar = getSupportActionBar(); 25 | if (actionBar != null) { 26 | actionBar.setDisplayHomeAsUpEnabled(true); 27 | } 28 | } 29 | 30 | } 31 | 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/ExampleMaterialPreferenceLicenseActivity.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | import android.content.Context; 3 | import android.support.annotation.NonNull; 4 | import android.view.MenuItem; 5 | 6 | import com.francoisdexemple.materialpreference.model.MaterialPreferenceList; 7 | 8 | 9 | public class ExampleMaterialPreferenceLicenseActivity extends ExampleMaterialPreferenceActivity { 10 | 11 | @NonNull @Override 12 | protected MaterialPreferenceList getMaterialPreferenceList(@NonNull final Context c) { 13 | return Demo.createMaterialPreferenceLicenseList(c, colorIcon); 14 | } 15 | 16 | @Override 17 | protected CharSequence getActivityTitle() { 18 | return getString(R.string.mp_title_licenses); 19 | } 20 | 21 | @Override 22 | public boolean onOptionsItemSelected(MenuItem item) { 23 | switch (item.getItemId()) { 24 | case android.R.id.home: 25 | finish(); 26 | return true; 27 | default: 28 | return false; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | import android.widget.Button; 11 | 12 | public class MainActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_main); 18 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 19 | setSupportActionBar(toolbar); 20 | 21 | Button fragmentButton = (Button) findViewById(R.id.fragment_button); 22 | fragmentButton.setOnClickListener(new View.OnClickListener() { 23 | @Override 24 | public void onClick(View v) { 25 | Intent i = new Intent(MainActivity.this, ExampleMaterialPreferenceFragmentActivity.class); 26 | startActivity(i); 27 | } 28 | }); 29 | 30 | } 31 | 32 | public void onActivityButtonPressed(View view) { 33 | Intent i = new Intent(MainActivity.this, ExampleMaterialPreferenceActivity.class); 34 | i.putExtra(ExampleMaterialPreferenceActivity.THEME_EXTRA, Integer.parseInt(view.getTag().toString())); 35 | startActivity(i); 36 | } 37 | 38 | @Override 39 | public boolean onCreateOptionsMenu(Menu menu) { 40 | // Inflate the menu; this adds items to the action bar if it is present. 41 | getMenuInflater().inflate(R.menu.menu_main, menu); 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean onOptionsItemSelected(MenuItem item) { 47 | // Handle action bar item clicks here. The action bar will 48 | // automatically handle clicks on the Home/Up button, so long 49 | // as you specify a parent activity in AndroidManifest.xml. 50 | int id = item.getItemId(); 51 | 52 | //noinspection SimplifiableIfStatement 53 | if (id == R.id.action_settings) { 54 | Intent i = new Intent(this, ExampleMaterialPreferenceActivity.class); 55 | startActivity(i); 56 | return true; 57 | } 58 | 59 | return super.onOptionsItemSelected(item); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/custom/MyCustomItem.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo.custom; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.os.Build; 6 | import android.support.annotation.DrawableRes; 7 | import android.support.annotation.IntDef; 8 | import android.support.annotation.StringRes; 9 | import android.text.Html; 10 | import android.util.TypedValue; 11 | import android.view.Gravity; 12 | import android.view.View; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | import android.widget.TextView; 16 | 17 | 18 | import com.francoisdexemple.materialpreference.holders.MaterialPreferenceItemViewHolder; 19 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceItem; 20 | import com.francoisdexemple.materialpreferencedemo.R; 21 | 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | 25 | import static android.view.View.GONE; 26 | 27 | public class MyCustomItem extends MaterialPreferenceItem { 28 | 29 | public interface OnClickListener { 30 | void onClick(); 31 | } 32 | 33 | 34 | 35 | @Retention(RetentionPolicy.SOURCE) 36 | @IntDef({GRAVITY_TOP, GRAVITY_MIDDLE, GRAVITY_BOTTOM}) 37 | public @interface IconGravity { 38 | } 39 | 40 | public static final int GRAVITY_TOP = 0; 41 | public static final int GRAVITY_MIDDLE = 1; 42 | public static final int GRAVITY_BOTTOM = 2; 43 | 44 | 45 | private CharSequence text = null; 46 | private int textRes = 0; 47 | 48 | private CharSequence subText = null; 49 | private int subTextRes = 0; 50 | 51 | private Drawable icon = null; 52 | private int iconRes = 0; 53 | private boolean showIcon = true; 54 | private int iconGravity = GRAVITY_MIDDLE; 55 | 56 | private MyCustomItem.OnClickListener onClickListener = null; 57 | 58 | @Override 59 | public int getType() { 60 | return MyViewTypeManager.ItemType.CUSTOM_ITEM; 61 | } 62 | 63 | @Override 64 | public String getDetailString() { 65 | return "MyCustomItem{" + 66 | "text=" + text + 67 | ", textRes=" + textRes + 68 | ", subText=" + subText + 69 | ", subTextRes=" + subTextRes + 70 | ", icon=" + icon + 71 | ", iconRes=" + iconRes + 72 | ", showIcon=" + showIcon + 73 | ", iconGravity=" + iconGravity + 74 | ", onClickListener=" + onClickListener + 75 | '}'; 76 | } 77 | 78 | public MyCustomItem(MyCustomItem item) { 79 | this.id = item.getId(); 80 | this.text = item.getText(); 81 | this.textRes = item.getTextRes(); 82 | this.subText = item.getSubText(); 83 | this.subTextRes = item.getSubTextRes(); 84 | this.icon = item.getIcon(); 85 | this.iconRes = item.getIconRes(); 86 | this.showIcon = item.shouldShowIcon(); 87 | this.iconGravity = item.getIconGravity(); 88 | this.onClickListener = item.getOnClickListener(); 89 | } 90 | 91 | @Override 92 | public MyCustomItem clone() { 93 | return new MyCustomItem(this); 94 | } 95 | 96 | public static MaterialPreferenceItemViewHolder getViewHolder(View view) { 97 | return new MyCustomItemViewHolder(view); 98 | } 99 | 100 | public static class MyCustomItemViewHolder extends MaterialPreferenceItemViewHolder implements View.OnClickListener { 101 | public final View view; 102 | public final ImageView icon; 103 | public final TextView text; 104 | public final TextView subText; 105 | public MyCustomItem.OnClickListener onClickListener; 106 | 107 | MyCustomItemViewHolder(View view) { 108 | super(view); 109 | this.view = view; 110 | icon = (ImageView) view.findViewById(R.id.mp_item_image); 111 | text = (TextView) view.findViewById(R.id.mp_item_text); 112 | subText = (TextView) view.findViewById(R.id.mp_action_item_subtext); 113 | 114 | view.setOnClickListener(this); 115 | onClickListener = null; 116 | } 117 | 118 | @Override 119 | public void onClick(View v) { 120 | if (onClickListener != null) { 121 | onClickListener.onClick(); 122 | } 123 | } 124 | } 125 | 126 | private MyCustomItem(Builder builder) { 127 | this.text = builder.text; 128 | this.textRes = builder.textRes; 129 | 130 | this.subText = builder.subText; 131 | this.subTextRes = builder.subTextRes; 132 | 133 | this.icon = builder.icon; 134 | this.iconRes = builder.iconRes; 135 | 136 | this.showIcon = builder.showIcon; 137 | 138 | this.iconGravity = builder.iconGravity; 139 | 140 | this.onClickListener = builder.onClickListener; 141 | } 142 | 143 | public MyCustomItem(CharSequence text, CharSequence subText, Drawable icon, OnClickListener onClickListener) { 144 | this.text = text; 145 | this.subText = subText; 146 | this.icon = icon; 147 | this.onClickListener = onClickListener; 148 | } 149 | 150 | public MyCustomItem(CharSequence text, CharSequence subText, Drawable icon) { 151 | this.text = text; 152 | this.subText = subText; 153 | this.icon = icon; 154 | } 155 | 156 | public MyCustomItem(int textRes, int subTextRes, int iconRes, OnClickListener onClickListener) { 157 | this.textRes = textRes; 158 | this.subTextRes = subTextRes; 159 | this.iconRes = iconRes; 160 | this.onClickListener = onClickListener; 161 | } 162 | 163 | public MyCustomItem(int textRes, int subTextRes, int iconRes) { 164 | this.textRes = textRes; 165 | this.subTextRes = subTextRes; 166 | this.iconRes = iconRes; 167 | } 168 | 169 | public CharSequence getText() { 170 | return text; 171 | } 172 | 173 | public int getTextRes() { 174 | return textRes; 175 | } 176 | 177 | public CharSequence getSubText() { 178 | return subText; 179 | } 180 | 181 | public int getSubTextRes() { 182 | return subTextRes; 183 | } 184 | 185 | public Drawable getIcon() { 186 | return icon; 187 | } 188 | 189 | public int getIconRes() { 190 | return iconRes; 191 | } 192 | 193 | public boolean shouldShowIcon() { 194 | return showIcon; 195 | } 196 | 197 | @IconGravity 198 | public int getIconGravity() { 199 | return iconGravity; 200 | } 201 | 202 | public MyCustomItem.OnClickListener getOnClickListener() { 203 | return onClickListener; 204 | } 205 | 206 | public static void setupItem(MyCustomItemViewHolder holder, MyCustomItem item, Context context) { 207 | CharSequence text = item.getText(); 208 | int textRes = item.getTextRes(); 209 | 210 | holder.text.setVisibility(View.VISIBLE); 211 | if (text != null) { 212 | holder.text.setText(text); 213 | } else if (textRes != 0) { 214 | holder.text.setText(textRes); 215 | } else { 216 | holder.text.setVisibility(GONE); 217 | } 218 | 219 | CharSequence subText = item.getSubText(); 220 | int subTextRes = item.getSubTextRes(); 221 | 222 | holder.subText.setVisibility(View.VISIBLE); 223 | if (subText != null) { 224 | holder.subText.setText(subText); 225 | } else if (subTextRes != 0) { 226 | holder.subText.setText(subTextRes); 227 | } else { 228 | holder.subText.setVisibility(GONE); 229 | } 230 | 231 | if (item.shouldShowIcon()) { 232 | holder.icon.setVisibility(View.VISIBLE); 233 | Drawable drawable = item.getIcon(); 234 | int drawableRes = item.getIconRes(); 235 | if (drawable != null) { 236 | holder.icon.setImageDrawable(drawable); 237 | } else if (drawableRes != 0) { 238 | holder.icon.setImageResource(drawableRes); 239 | } 240 | } else { 241 | holder.icon.setVisibility(GONE); 242 | } 243 | 244 | LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.icon.getLayoutParams(); 245 | switch (item.getIconGravity()) { 246 | case MyCustomItem.GRAVITY_TOP: 247 | params.gravity = Gravity.TOP; 248 | break; 249 | case MyCustomItem.GRAVITY_MIDDLE: 250 | params.gravity = Gravity.CENTER_VERTICAL; 251 | break; 252 | case MyCustomItem.GRAVITY_BOTTOM: 253 | params.gravity = Gravity.BOTTOM; 254 | break; 255 | } 256 | holder.icon.setLayoutParams(params); 257 | 258 | int pL = 0, pT = 0, pR = 0, pB = 0; 259 | if (Build.VERSION.SDK_INT < 21) { 260 | pL = holder.view.getPaddingLeft(); 261 | pT = holder.view.getPaddingTop(); 262 | pR = holder.view.getPaddingRight(); 263 | pB = holder.view.getPaddingBottom(); 264 | } 265 | 266 | if (item.getOnClickListener() != null) { 267 | TypedValue outValue = new TypedValue(); 268 | context.getTheme().resolveAttribute(R.attr.selectableItemBackground, outValue, true); 269 | holder.view.setBackgroundResource(outValue.resourceId); 270 | holder.onClickListener = item.getOnClickListener(); 271 | holder.view.setSoundEffectsEnabled(true); 272 | } else { 273 | TypedValue outValue = new TypedValue(); 274 | context.getTheme().resolveAttribute(R.attr.selectableItemBackground, outValue, false); 275 | holder.view.setBackgroundResource(outValue.resourceId); 276 | holder.onClickListener = null; 277 | holder.view.setSoundEffectsEnabled(false); 278 | } 279 | 280 | if (Build.VERSION.SDK_INT < 21) { 281 | holder.view.setPadding(pL, pT, pR, pB); 282 | } 283 | } 284 | 285 | public static class Builder { 286 | 287 | private CharSequence text = null; 288 | @StringRes 289 | private int textRes = 0; 290 | 291 | private CharSequence subText = null; 292 | @StringRes 293 | private int subTextRes = 0; 294 | 295 | private Drawable icon = null; 296 | @DrawableRes 297 | private int iconRes = 0; 298 | 299 | private boolean showIcon = true; 300 | 301 | @IconGravity 302 | private int iconGravity = GRAVITY_MIDDLE; 303 | 304 | MyCustomItem.OnClickListener onClickListener; 305 | 306 | public Builder text(CharSequence text) { 307 | this.text = text; 308 | this.textRes = 0; 309 | return this; 310 | } 311 | 312 | public Builder text(@StringRes int text) { 313 | this.textRes = text; 314 | this.text = null; 315 | return this; 316 | } 317 | 318 | public Builder subText(CharSequence subText) { 319 | this.subText = subText; 320 | this.subTextRes = 0; 321 | return this; 322 | } 323 | 324 | public Builder subText(@StringRes int subTextRes) { 325 | this.subText = null; 326 | this.subTextRes = subTextRes; 327 | return this; 328 | } 329 | 330 | public Builder subTextHtml(String subTextHtml) { 331 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 332 | this.subText = Html.fromHtml(subTextHtml, Html.FROM_HTML_MODE_LEGACY); 333 | } else { 334 | //noinspection deprecation 335 | this.subText = Html.fromHtml(subTextHtml); 336 | } 337 | this.subTextRes = 0; 338 | return this; 339 | } 340 | 341 | public Builder icon(Drawable icon) { 342 | this.icon = icon; 343 | this.iconRes = 0; 344 | return this; 345 | } 346 | 347 | public Builder icon(@DrawableRes int iconRes) { 348 | this.icon = null; 349 | this.iconRes = iconRes; 350 | return this; 351 | } 352 | 353 | public Builder showIcon(boolean showIcon) { 354 | this.showIcon = showIcon; 355 | return this; 356 | } 357 | 358 | public Builder setIconGravity(@IconGravity int iconGravity) { 359 | this.iconGravity = iconGravity; 360 | return this; 361 | } 362 | 363 | public Builder setOnClickListener(MyCustomItem.OnClickListener onClickListener) { 364 | this.onClickListener = onClickListener; 365 | return this; 366 | } 367 | 368 | public MyCustomItem build() { 369 | return new MyCustomItem(this); 370 | } 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /app/src/main/java/com/francoisdexemple/materialpreferencedemo/custom/MyViewTypeManager.java: -------------------------------------------------------------------------------- 1 | package com.francoisdexemple.materialpreferencedemo.custom; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | 6 | 7 | import com.francoisdexemple.materialpreference.holders.MaterialPreferenceItemViewHolder; 8 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceActionItem; 9 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceCheckBoxItem; 10 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceItem; 11 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceSwitchItem; 12 | import com.francoisdexemple.materialpreference.items.MaterialPreferenceTitleItem; 13 | import com.francoisdexemple.materialpreference.util.ViewTypeManager; 14 | import com.francoisdexemple.materialpreferencedemo.R; 15 | 16 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemLayout.ACTION_LAYOUT; 17 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemLayout.CHECKBOX_LAYOUT; 18 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemLayout.CUSTOM_LAYOUT; 19 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemLayout.SWITCH_LAYOUT; 20 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemLayout.TITLE_LAYOUT; 21 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemType.ACTION_ITEM; 22 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemType.CHECKBOX_ITEM; 23 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemType.CUSTOM_ITEM; 24 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemType.SWITCH_ITEM; 25 | import static com.francoisdexemple.materialpreferencedemo.custom.MyViewTypeManager.ItemType.TITLE_ITEM; 26 | 27 | public class MyViewTypeManager extends ViewTypeManager { 28 | 29 | public static final class ItemType { 30 | public static final int ACTION_ITEM = ViewTypeManager.ItemType.ACTION_ITEM; 31 | public static final int TITLE_ITEM = ViewTypeManager.ItemType.TITLE_ITEM; 32 | public static final int CUSTOM_ITEM = 10; 33 | public static final int SWITCH_ITEM = ViewTypeManager.ItemType.SWITCH_ITEM; 34 | public static final int CHECKBOX_ITEM = ViewTypeManager.ItemType.CHECKBOX_ITEM; 35 | } 36 | 37 | public static final class ItemLayout { 38 | public static final int ACTION_LAYOUT = ViewTypeManager.ItemLayout.ACTION_LAYOUT; 39 | public static final int TITLE_LAYOUT = ViewTypeManager.ItemLayout.TITLE_LAYOUT; 40 | public static final int CUSTOM_LAYOUT = R.layout.custom_item; 41 | public static final int SWITCH_LAYOUT = ViewTypeManager.ItemLayout.SWITCH_LAYOUT; 42 | public static final int CHECKBOX_LAYOUT = ViewTypeManager.ItemLayout.CHECKBOX_LAYOUT; 43 | } 44 | 45 | 46 | public int getLayout(int itemType) { 47 | switch (itemType) { 48 | case ACTION_ITEM: 49 | return ACTION_LAYOUT; 50 | case TITLE_ITEM: 51 | return TITLE_LAYOUT; 52 | case CUSTOM_ITEM: 53 | return CUSTOM_LAYOUT; 54 | case CHECKBOX_ITEM: 55 | return CHECKBOX_LAYOUT; 56 | case SWITCH_ITEM: 57 | return SWITCH_LAYOUT; 58 | default: 59 | return -1; 60 | } 61 | } 62 | 63 | public MaterialPreferenceItemViewHolder getViewHolder(int itemType, View view) { 64 | switch (itemType) { 65 | case ACTION_ITEM: 66 | return MaterialPreferenceActionItem.getViewHolder(view); 67 | case TITLE_ITEM: 68 | return MaterialPreferenceTitleItem.getViewHolder(view); 69 | case CUSTOM_ITEM: 70 | return MyCustomItem.getViewHolder(view); 71 | case SWITCH_ITEM: 72 | return MaterialPreferenceSwitchItem.getViewHolder(view); 73 | case CHECKBOX_ITEM: 74 | return MaterialPreferenceCheckBoxItem.getViewHolder(view); 75 | default: 76 | return null; 77 | } 78 | } 79 | 80 | public void setupItem(int itemType, MaterialPreferenceItemViewHolder holder, MaterialPreferenceItem item, Context context) { 81 | switch (itemType) { 82 | case ACTION_ITEM: 83 | MaterialPreferenceActionItem.setupItem((MaterialPreferenceActionItem.MaterialPreferenceActionItemViewHolder) holder, (MaterialPreferenceActionItem) item, context); 84 | break; 85 | case TITLE_ITEM: 86 | MaterialPreferenceTitleItem.setupItem((MaterialPreferenceTitleItem.MaterialPreferenceTitleItemViewHolder) holder, (MaterialPreferenceTitleItem) item, context); 87 | break; 88 | case CUSTOM_ITEM: 89 | MyCustomItem.setupItem((MyCustomItem.MyCustomItemViewHolder) holder, (MyCustomItem) item, context); 90 | break; 91 | case SWITCH_ITEM: 92 | MaterialPreferenceSwitchItem.setupItem((MaterialPreferenceSwitchItem.MaterialPreferenceSwitchItemViewHolder) holder, (MaterialPreferenceSwitchItem) item, context); 93 | break; 94 | case CHECKBOX_ITEM: 95 | MaterialPreferenceCheckBoxItem.setupItem((MaterialPreferenceCheckBoxItem.MaterialPreferenceCheckBoxItemViewHolder) holder, (MaterialPreferenceCheckBoxItem) item,context); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_example_material_preference_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_example_material_preference_fragment.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 |