Aidan Follestad 6 лет назад
Родитель
Сommit
8dc88b0095
100 измененных файлов с 3278 добавлено и 9127 удалено
  1. 0 17
      .gitattributes
  2. 8 12
      .github/ISSUE_TEMPLATE.md
  3. 2 2
      .travis.yml
  4. 73 0
      LICENSE.md
  5. 0 21
      LICENSE.txt
  6. 645 1080
      README.md
  7. 1339 0
      README_OLD.md
  8. BIN
      art/basic.png
  9. BIN
      art/basic_list.png
  10. BIN
      art/basic_with_buttons.png
  11. BIN
      art/checkbox_prompt.png
  12. BIN
      art/color_chooser.png
  13. BIN
      art/color_chooser_sub.png
  14. BIN
      art/custom_view.png
  15. BIN
      art/file_chooser.png
  16. BIN
      art/file_emptytext.png
  17. BIN
      art/icon.png
  18. BIN
      art/input.png
  19. BIN
      art/input_max_length.png
  20. BIN
      art/multi_choice_list.png
  21. BIN
      art/readmeshowcase.png
  22. BIN
      art/showcase20.jpg
  23. BIN
      art/single_choice_list.png
  24. BIN
      art/stacked_buttons.png
  25. 26 0
      bintrayconfig.gradle
  26. 22 31
      build.gradle
  27. 0 0
      color/.gitignore
  28. 38 0
      color/build.gradle
  29. 21 0
      color/proguard-rules.pro
  30. 2 0
      color/src/main/AndroidManifest.xml
  31. 77 0
      color/src/main/java/com/afollestad/materialdialogs/color/ColorCircleView.kt
  32. 173 0
      color/src/main/java/com/afollestad/materialdialogs/color/ColorGridAdapter.kt
  33. 75 0
      color/src/main/java/com/afollestad/materialdialogs/color/DialogColorChooserExt.kt
  34. 37 0
      color/src/main/java/com/afollestad/materialdialogs/color/utilext/ColorUtilExt.kt
  35. 20 0
      color/src/main/java/com/afollestad/materialdialogs/color/utilext/ViewUtilExt.kt
  36. 0 0
      color/src/main/res-public/values/public.xml
  37. 10 0
      color/src/main/res/drawable/icon_back_black.xml
  38. 10 0
      color/src/main/res/drawable/icon_back_white.xml
  39. 10 0
      color/src/main/res/drawable/icon_checkmark_black.xml
  40. 10 0
      color/src/main/res/drawable/icon_checkmark_white.xml
  41. 10 0
      color/src/main/res/layout/md_color_chooser_grid.xml
  42. 29 0
      color/src/main/res/layout/md_color_grid_item.xml
  43. 22 0
      color/src/main/res/layout/md_color_grid_item_goup.xml
  44. 4 0
      color/src/main/res/values-land/integers.xml
  45. 4 0
      color/src/main/res/values-large-land/integers.xml
  46. 4 0
      color/src/main/res/values-large/integers.xml
  47. 7 0
      color/src/main/res/values/dimens.xml
  48. 4 0
      color/src/main/res/values/integers.xml
  49. 0 47
      commons/build.gradle
  50. 0 3
      commons/src/main/AndroidManifest.xml
  51. 0 208
      commons/src/main/java/com/afollestad/materialdialogs/color/CircleView.java
  52. 0 808
      commons/src/main/java/com/afollestad/materialdialogs/color/ColorChooserDialog.java
  53. 0 382
      commons/src/main/java/com/afollestad/materialdialogs/color/ColorPalette.java
  54. 0 27
      commons/src/main/java/com/afollestad/materialdialogs/color/FillGridView.java
  55. 0 2
      commons/src/main/java/com/afollestad/materialdialogs/color/package-info.java
  56. 0 369
      commons/src/main/java/com/afollestad/materialdialogs/folderselector/FileChooserDialog.java
  57. 0 350
      commons/src/main/java/com/afollestad/materialdialogs/folderselector/FolderChooserDialog.java
  58. 0 2
      commons/src/main/java/com/afollestad/materialdialogs/folderselector/package-info.java
  59. 0 180
      commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialDialogPreference.java
  60. 0 267
      commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialEditTextPreference.java
  61. 0 226
      commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialListPreference.java
  62. 0 225
      commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialMultiSelectListPreference.java
  63. 0 76
      commons/src/main/java/com/afollestad/materialdialogs/prefs/PrefUtil.java
  64. 0 2
      commons/src/main/java/com/afollestad/materialdialogs/prefs/package-info.java
  65. 0 118
      commons/src/main/java/com/afollestad/materialdialogs/simplelist/MaterialSimpleListAdapter.java
  66. 0 142
      commons/src/main/java/com/afollestad/materialdialogs/simplelist/MaterialSimpleListItem.java
  67. 0 2
      commons/src/main/java/com/afollestad/materialdialogs/simplelist/package-info.java
  68. 0 8
      commons/src/main/res/drawable/gray_circle.xml
  69. 0 19
      commons/src/main/res/layout/md_dialog_colorchooser.xml
  70. 0 74
      commons/src/main/res/layout/md_preference_custom.xml
  71. 0 36
      commons/src/main/res/layout/md_simplelist_item.xml
  72. 0 235
      commons/src/main/res/layout/md_stub_colorchooser_custom.xml
  73. 0 14
      commons/src/main/res/layout/md_stub_colorchooser_grid.xml
  74. 0 28
      commons/src/main/res/layout/md_stub_inputpref.xml
  75. 0 6
      commons/src/main/res/values-large/dimens.xml
  76. 0 8
      commons/src/main/res/values/attrs.xml
  77. 0 12
      commons/src/main/res/values/dimens.xml
  78. 0 12
      commons/src/main/res/values/strings.xml
  79. 31 39
      core/build.gradle
  80. 3 3
      core/src/main/AndroidManifest.xml
  81. 0 227
      core/src/main/java/com/afollestad/materialdialogs/DefaultRvAdapter.java
  82. 0 8
      core/src/main/java/com/afollestad/materialdialogs/DialogAction.java
  83. 0 67
      core/src/main/java/com/afollestad/materialdialogs/DialogBase.java
  84. 0 553
      core/src/main/java/com/afollestad/materialdialogs/DialogInit.java
  85. 0 42
      core/src/main/java/com/afollestad/materialdialogs/GravityEnum.java
  86. 0 2149
      core/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java
  87. 323 0
      core/src/main/java/com/afollestad/materialdialogs/MaterialDialog.kt
  88. 0 11
      core/src/main/java/com/afollestad/materialdialogs/StackingBehavior.java
  89. 0 7
      core/src/main/java/com/afollestad/materialdialogs/Theme.java
  90. 22 0
      core/src/main/java/com/afollestad/materialdialogs/Theme.kt
  91. 20 0
      core/src/main/java/com/afollestad/materialdialogs/WhichButton.kt
  92. 16 0
      core/src/main/java/com/afollestad/materialdialogs/actions/DialogActionExt.kt
  93. 65 0
      core/src/main/java/com/afollestad/materialdialogs/callbacks/DialogCallbackExt.kt
  94. 52 0
      core/src/main/java/com/afollestad/materialdialogs/checkbox/DialogCheckboxExt.kt
  95. 64 0
      core/src/main/java/com/afollestad/materialdialogs/customview/DialogCustomViewExt.kt
  96. 0 28
      core/src/main/java/com/afollestad/materialdialogs/internal/AllCapsTransformationMethod.java
  97. 0 8
      core/src/main/java/com/afollestad/materialdialogs/internal/MDAdapter.java
  98. 0 93
      core/src/main/java/com/afollestad/materialdialogs/internal/MDButton.java
  99. 0 650
      core/src/main/java/com/afollestad/materialdialogs/internal/MDRootLayout.java
  100. 0 191
      core/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java

+ 0 - 17
.gitattributes

@@ -1,17 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-
-# Custom for Visual Studio
-*.cs     diff=csharp
-
-# Standard to msysgit
-*.doc	 diff=astextplain
-*.DOC	 diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot  diff=astextplain
-*.DOT  diff=astextplain
-*.pdf  diff=astextplain
-*.PDF	 diff=astextplain
-*.rtf	 diff=astextplain
-*.RTF	 diff=astextplain

+ 8 - 12
.github/ISSUE_TEMPLATE.md

@@ -1,23 +1,21 @@
 (`[x]` becomes a filled in checkbox, `[ ]` is an empty one)
 
-- [ ] *I understand that dialogs which require a combination of different dialog types provided by this library (e.g. list + progress, input + checkbox) require a **custom view**.*
 - [ ] I have verified there are [no duplicate active or recent bugs, questions, or requests](https://github.com/afollestad/material-dialogs/issues?q=is%3Aissue+is%3Aclosed)
-- [ ] I have verified that I am using the latest version of Material Dialogs.
+- [ ] I understand that versions below 2.0.0 will no longer be supported for updates.
 - [ ] I have given my issue a non-generic title.
 - [ ] I have [read over the documentation](https://github.com/afollestad/material-dialogs/blob/master/README.md) (before asking questions on how to do something).
 
 ---
 
 ###### Include the following:
- - Material Dialogs version: `0.x.x.x`
- - Device OS version: `7.1.1`
- - Device Manufacturer: `Google`
- - Device Name: `Pixel XL`
 
-Also, please wrap your code with correct syntax highlighting.
+ - Material Dialogs version: `0.x.x`
+ - Affected device: Google Pixel 2 XL with Android 9.0
 
-```java
-System.out.println("Hello, world!");
+Also, please wrap your code with correct syntax highlighting (not just indents).
+
+```kotlin
+println("Hello, world!")
 ```
 
 ```xml
@@ -28,9 +26,7 @@ System.out.println("Hello, world!");
  
 ###### Reproduction Steps
 
-1. 
-2. 
-3. 
+1.
 
 ---
 

+ 2 - 2
.travis.yml

@@ -4,8 +4,8 @@ android:
   components:
     - tools
     - platform-tools
-    - build-tools-27.0.3
-    - android-27
+    - build-tools-28.0.1
+    - android-28
     - extra-android-support
     - extra-android-m2repository
     - extra-google-m2repository

+ 73 - 0
LICENSE.md

@@ -0,0 +1,73 @@
+###### Apache License, Version 2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
+
+### TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+###### 1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+###### 2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+###### 3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+###### 4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+###### 5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+###### 7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+###### 8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+###### 9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+### END OF TERMS AND CONDITIONS
+
+### APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+### Copyright 2018 Aidan Follestad
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

+ 0 - 21
LICENSE.txt

@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014-2016 Aidan Michael Follestad
-
-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:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-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.

+ 645 - 1080
README.md

@@ -1,1339 +1,904 @@
 # Material Dialogs
 
-[ ![Core](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Acore/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Acore/_latestVersion)
-[ ![Commons](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Acommons/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Acommons/_latestVersion)
+**Looking for the README for versions before 2.0? [Click here](README_OLD.md). Note that pre-2.0 
+versions will no longer receive support.**
+
 [![Build Status](https://travis-ci.org/afollestad/material-dialogs.svg)](https://travis-ci.org/afollestad/material-dialogs)
 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a4acc30a9ce440087f7688735359bb8)](https://www.codacy.com/app/drummeraidan_50/material-dialogs?utm_source=github.com&utm_medium=referral&utm_content=afollestad/material-dialogs&utm_campaign=Badge_Grade)
-[![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/afollestad/material-dialogs/blob/master/LICENSE.txt)
-
-![Screenshots](https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/readmeshowcase.png)
-
-# Table of Contents (Core)
-
-1. [Sample Project](https://github.com/afollestad/material-dialogs#sample-project)
-2. [Gradle Dependency](https://github.com/afollestad/material-dialogs#gradle-dependency)
-    1. [Repository](https://github.com/afollestad/material-dialogs#repository)
-    2. [Core](https://github.com/afollestad/material-dialogs#core)
-    3. [Commons](https://github.com/afollestad/material-dialogs#commons)
-3. [What's New](https://github.com/afollestad/material-dialogs#whats-new)
-4. [Basic Dialog](https://github.com/afollestad/material-dialogs#basic-dialog)
-5. [Dismissing Dialogs](https://github.com/afollestad/material-dialogs#dismissing-dialogs)
-6. [Displaying an Icon](https://github.com/afollestad/material-dialogs#displaying-an-icon)
-7. [Stacked Action Buttons](https://github.com/afollestad/material-dialogs#stacked-action-buttons)
-    1. [Stacking Behavior](https://github.com/afollestad/material-dialogs#stacking-behavior)
-8. [Neutral Action Button](https://github.com/afollestad/material-dialogs#neutral-action-button)
-9. [Callbacks](https://github.com/afollestad/material-dialogs#callbacks)
-10. [CheckBox Prompts](https://github.com/afollestad/material-dialogs#checkbox-prompts)
-11. [List Dialogs](https://github.com/afollestad/material-dialogs#list-dialogs)
-12. [Single Choice List Dialogs](https://github.com/afollestad/material-dialogs#single-choice-list-dialogs)
-    1. [Coloring Radio Buttons](https://github.com/afollestad/material-dialogs#coloring-radio-buttons)
-13. [Multi Choice List Dialogs](https://github.com/afollestad/material-dialogs#multi-choice-list-dialogs)
-    1. [Coloring Check Boxes](https://github.com/afollestad/material-dialogs#coloring-check-boxes)
-14. [Assigning IDs to List Item Views](https://github.com/afollestad/material-dialogs#assigning-ids-to-list-item-views)
-15. [Custom List Dialogs](https://github.com/afollestad/material-dialogs#custom-list-dialogs)
-16. [Custom Views](https://github.com/afollestad/material-dialogs#custom-views)
-    1. [Later Access](https://github.com/afollestad/material-dialogs#later-access)
-17. [Typefaces](https://github.com/afollestad/material-dialogs#typefaces)
-18. [Getting and Setting Action Buttons](https://github.com/afollestad/material-dialogs#getting-and-setting-action-buttons)
-19. [Theming](https://github.com/afollestad/material-dialogs#theming)
-    1. [Basics](https://github.com/afollestad/material-dialogs#basics)
-    2. [Colors](https://github.com/afollestad/material-dialogs#colors)
-    3. [Selectors](https://github.com/afollestad/material-dialogs#selectors)
-    4. [Gravity](https://github.com/afollestad/material-dialogs#gravity)
-    5. [Material Palette](https://github.com/afollestad/material-dialogs#material-palette)
-20. [Global Theming](https://github.com/afollestad/material-dialogs#global-theming)
-21. [Show, Cancel, and Dismiss Callbacks](https://github.com/afollestad/material-dialogs#show-cancel-and-dismiss-callbacks)
-22. [Input Dialogs](https://github.com/afollestad/material-dialogs#input-dialogs)
-    1. [Coloring the EditText](https://github.com/afollestad/material-dialogs#coloring-the-edittext)
-    2. [Limiting Input Length](https://github.com/afollestad/material-dialogs#limiting-input-length)
-    3. [Custom Invalidation](https://github.com/afollestad/material-dialogs#custom-invalidation)
-23. [Progress Dialogs](https://github.com/afollestad/material-dialogs#progress-dialogs)
-    1. [Proguard](https://github.com/afollestad/material-dialogs#proguard)
-    2. [Indeterminate Progress Dialogs](https://github.com/afollestad/material-dialogs#indeterminate-progress-dialogs)
-    3. [Determinate (Seek Bar) Progress Dialogs](https://github.com/afollestad/material-dialogs#determinate-seek-bar-progress-dialogs)
-    4. [Make an Indeterminate Dialog Horizontal](https://github.com/afollestad/material-dialogs#make-an-indeterminate-dialog-horizontal)
-    5. [Coloring the Progress Bar](https://github.com/afollestad/material-dialogs#coloring-the-progress-bar)
-    6. [Custom Number and Progress Formats](https://github.com/afollestad/material-dialogs#custom-number-and-progress-formats)
-24. [Tint Helper](https://github.com/afollestad/material-dialogs#tint-helper)
-25. [Misc](https://github.com/afollestad/material-dialogs#misc)
-
-# Table of Contents (Commons)
-
-1. [Color Chooser Dialogs](https://github.com/afollestad/material-dialogs#color-chooser-dialogs)
-    1. [Finding Visible Dialogs](https://github.com/afollestad/material-dialogs#finding-visible-dialogs)
-    2. [User Color Input](https://github.com/afollestad/material-dialogs#user-color-input)
-2. [File Selector Dialogs](https://github.com/afollestad/material-dialogs#file-selector-dialogs)
-3. [Folder Selector Dialogs](https://github.com/afollestad/material-dialogs#folder-selector-dialogs)
-4. [Preference Dialogs](https://github.com/afollestad/material-dialogs#preference-dialogs)
-5. [Simple List Dialogs](https://github.com/afollestad/material-dialogs#simple-list-dialogs) 
-
-------
-
-# Sample Project
-
-You can download the latest sample APK from this repo here: https://github.com/afollestad/material-dialogs/blob/master/sample/sample.apk
-
-It's also on Google Play:
-
-<a href="https://play.google.com/store/apps/details?id=com.afollestad.materialdialogssample" target="_blank">
-  <img alt="Get it on Google Play"
-       src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" height="60"/>
-</a>
-
-Having the sample project installed is a good way to be notified of new releases. Although Watching this 
-repository will allow GitHub to email you whenever I publish a release.
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
 
----
+![Screenshots](https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/showcase20.jpg)
 
-# Gradle Dependency
+# Table of Contents - Core
 
-### Repository
+1. [Gradle Dependency](#gradle-dependency)
+2. [Changes in Version 2](#changes-in-version-2)
+3. [Basics](#basics)
+4. [Action Buttons](#action-buttons)
+5. [Adding an Icon](#adding-an-icon)
+6. [Callbacks](#callbacks)
+7. [Kotlin Extras](#kotlin-extras)
+8. [Dismissing](#dismissing)
+9. [Lists](#lists)
+    1. [Plain](#plain)
+    2. [Single Choice](#single-choice)
+    3. [Multiple Choice](#multiple-choice)
+    4. [Custom Adapters](#custom-adapters)
+10. [Checkbox Prompts](#checkbox-prompts)
+11. [Custom Views](#custom-views)
+12. [Miscellaneous](#miscellaneous)
 
-The Gradle dependency is available via [jCenter](https://bintray.com/drummer-aidan/maven/material-dialogs:core/view).
-jCenter is the default Maven repository used by Android Studio.
+# Table of Contents - Input
 
-The minimum API level supported by this library is API 14.
+1. [Gradle Dependency](#gradle-dependency-1)
+2. [Text Input](#text-input)
+    1. [Basics](#basics-1)
+    2. [Hints and Prefill](#hints-and-prefill)
+    3. [Input Types](#input-types)
+    4. [Max Length](#max-length)
+    5. [Custom Validation](#custom-validation)
 
-### Core
+# Table of Contents - Files
 
-The *core* module contains all the major classes of this library, including `MaterialDialog`.
-You can create basic, list, single/multi choice, progress, input, etc. dialogs with core.
+1. [Gradle Dependency](#gradle-dependency-2)
+2. [File Choosers](#file-choosers)
+    1. [Basics](#basics-2)
+    2. [Filter](#filter)
+    3. [Empty Text](#empty-text)
+3. [Folder Choosers](#folder-choosers)
+    1. [Basics](#basics-3)
+    2. [Filter](#filter-2)
+    3. [Empty Text](#empty-text-1)
 
-```gradle
-dependencies {
-	// ... other dependencies here
-    implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
-}
-```
+# Table of Contents - Color
 
-### Commons
+1. [Gradle Dependency](#gradle-dependency-3)
+2. [Color Choosers](#color-choosers)
+    1. [Basics](#basics-4)
+    2. [Sub Colors](#sub-colors) 
+
+---
 
-The *commons* module contains extensions to the library that not everyone may need. This includes the
-`ColorChooserDialog`, `FolderChooserDialog`, the Material `Preference` classes, and `MaterialSimpleListAdapter`/`MaterialSimpleListItem`.
+# Core
+
+## Gradle Dependency
+
+[ ![Core](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Acore/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Acore/_latestVersion)
+
+The `core` module contains everything you need to get started with the library. It contains all
+core and normal-use functionality.
 
 ```gradle
 dependencies {
-    // ... other dependencies here
-    implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
+	
+    implementation 'com.afollestad.material-dialogs:core:2.0.0-alpha01'
 }
 ```
 
-It's likely that new extensions will be added to commons later.
+## Changes in Version 2
 
----
-
-# What's New
+The whole library has been rebuilt, layouts and everything. The library is 100% Kotlin. APIs have 
+changed and a lot of things will be broken if you upgrade from the older version. Other things 
+to note:
 
-See the project's Releases page for a list of versions with their changelogs.
+1. **This library will be more opinionated. Not every feature request will be implemented.**
+2. There is no longer a separate `Builder` class, it's all-in-one.
+3. All main classes exist in the `core` module, the extension modules take advantage of Kotlin 
+extensions to append functionality to it (such as input dialogs, color dialogs, etc.). This way,
+you can include only what your app needs.
+4. The use of the neutral button is deprecated to discourage use, see the 
+[newer Material guidelines](https://material.io/design/components/dialogs.html#actions).
+5. There is no longer a progress dialog included in library, since they are discouraged by Google, 
+and discouraged by me. You should prefer a non-blocking inline progress indicator.
+6. No dynamic color support, your dialogs will match your app theme. *I will be making sure 
+[Aesthetic](https://github.com/afollestad/aesthetic) works correctly with this library if you really 
+need dynamic theming.*
+7. Other things will probably be added here.
 
-### [View Releases](https://github.com/afollestad/material-dialogs/releases)
+## Basics
 
-If you Watch this repository, GitHub will send you an email every time I publish an update.
+Here's a very basic example of creating and showing a dialog:
 
----
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/basic.png" width="200px" />
 
-# Basic Dialog
+```kotlin
+MaterialDialog(this)
+  .title(R.string.your_title)
+  .message(R.string.your_message)
+  .show()
+```
 
-First of all, note that `MaterialDialog` extends `DialogBase`, which extends `android.app.Dialog`.
+`this` should be a `Context` which is attached to a window, like an `Activity`.
 
-Here's a basic example that mimics the dialog you see on Google's Material design guidelines
-(here: http://www.google.com/design/spec/components/dialogs.html#dialogs-usage). Note that you can
-always substitute literal strings and string resources for methods that take strings, the same goes
-for color resources (e.g. `titleColor` and `titleColorRes`).
+If you wanted to pass in literal strings instead of string resources:
 
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.agree)
-        .negativeText(R.string.disagree)
-        .show();
+```kotlin
+MaterialDialog(this)
+  .title(text = "Your Title")
+  .message(text = "Your Message")
+  .show()
 ```
 
-**Your Activities need to inherit the AppCompat themes in order to work correctly with this library.**
-The Material dialog will automatically match the `positiveColor` (which is used on the positive action
-button) to the `colorAccent` attribute of your styles.xml theme.
+Note that you can setup a dialog without immediately showing it, as well:
 
-If the content is long enough, it will become scrollable and a divider will be displayed above the action buttons.
+```kotlin
+val dialog = MaterialDialog(this)
+  .title(R.string.your_title)
+  .message(R.string.your_message)
+  
+dialog.show()
+```
 
----
+## Action Buttons
 
-# Dismissing Dialogs
+There are simple methods for adding action buttons:
 
-I've had lots of issues asking how you dismiss a dialog. It works the same way that `AlertDialog` does, as
-both `AlertDialog` and `MaterialDialog` are an instance of `android.app.Dialog` (which is where `dismiss()`
-and `show()` come from). You cannot dismiss a dialog using it's `Builder`. You can only dismiss a
-dialog using the dialog itself.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/basic_with_buttons.png" width="200px" />
 
-There's many ways you can get an instance of `MaterialDialog`. The two major ways are through the `show()` and `build()`
-methods of `MaterialDialog.Builder`.
+```kotlin
+MaterialDialog(this)
+  ...
+  .positiveButton(R.string.agree)
+  .negativeButton(R.string.disagree)
+  .show()
+```
 
-Through `show()`, which immediately shows the dialog and returns the visible dialog:
+You can use literal strings here as well:
 
-```java
-MaterialDialog dialog = new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.agree)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .positiveButton(text = "Agree")
+  .negativeButton(text = "Disagree")
+  .show()
 ```
 
-Through `build()`, which only builds the dialog but doesn't show it until you say so:
+---
 
-```java
-MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.agree);
+Listening for clicks on the buttons is as simple as adding a lambda to the end:
 
-MaterialDialog dialog = builder.build();
-dialog.show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .positiveButton(R.string.agree) { dialog ->
+    // Do something
+  }
+  .negativeButton(R.string.disagree) { dialog ->
+    // Do something
+  }
+  .show()
 ```
 
-Once the dialog is shown, you can dismiss it:
-
-```java
-dialog.dismiss();
-```
+If action buttons together are too long to fit in the dialog's width, they will be automatically
+stacked:
 
-There are other various places where the `MaterialDialog` instance is given, such as in some callbacks
- that are discussed in future sections below.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/stacked_buttons.png" width="200px" />
 
----
+## Adding an Icon
 
-# Displaying an Icon
+You can display an icon to the left of the title:
 
-MaterialDialog supports the display of an icon just like the stock AlertDialog; it will go to the left of the title.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/icon.png" width="200px" />
 
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.agree)
-        .icon(R.drawable.icon)
-        .show();
+```kotlin
+MaterialDialog(this)
+  .title(R.string.your_title)
+  .icon(R.drawable.your_icon)
+  .show()
 ```
 
-You can limit the maximum size of the icon using the `limitIconToDefaultSize()`, `maxIconSize(int size)`,
- or `maxIconSizeRes(int sizeRes)` Builder methods.
+You can pass a Drawable instance as well:
 
----
+```kotlin
+val myDrawable: Drawable = // ...
+MaterialDialog(this)
+  ...
+  .icon(drawable = myDrawable)
+  .show()
+```
 
-# Stacked Action Buttons
+## Callbacks
 
-If you have multiple action buttons that together are too wide to fit on one line, the dialog will stack the
-buttons to be vertically oriented.
+There are a few lifecycle callbacks you can hook into:
 
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.longer_positive)
-        .negativeText(R.string.negative)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .onPreShow { dialog -> }
+  .onShow { dialog -> }
+  .onDismiss { dialog -> }
+  .onCancel { dialog -> }
+  .show()
 ```
 
-### Stacking Behavior
+## Kotlin Extras
 
-You can set stacking behavior from the `Builder`:
+There's a cool way you can setup and show dialogs in a simple call with Kotlin:
 
-```java
-new MaterialDialog.Builder(this)
-    ...
-    .stackingBehavior(StackingBehavior.ADAPTIVE)  // the default value
-    .show();
+```kotlin
+MaterialDialog(this).show {
+  title(R.string.your_title)
+  message(R.string.your_message)
+  positiveButton(R.string.agree) { }
+  negativeButton(R.string.disagree) { }
+}
 ```
 
----
+## Dismissing 
 
-# Neutral Action Button
+Dismissing a dialog closes it, it's just a simple method inherited from the parent `Dialog` class:
 
-You can specify neutral text in addition to the positive and negative text. It will show the neutral
-action on the far left.
+```kotlin
+val dialog: MaterialDialog = // ...
 
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.agree)
-        .negativeText(R.string.disagree)
-        .neutralText(R.string.more_info)
-        .show();
+dialog.dismiss()
 ```
 
----
+## Lists
 
-# Callbacks
-
-**As of version 0.8.2.0, the `callback()` Builder method is deprecated in favor of the individual callback methods
-  discussed below. Earlier versions will still require use of `ButtonCallback`.**
-
-To know when the user selects an action button, you set callbacks:
-
-```java
-new MaterialDialog.Builder(this)
-    .onPositive(new MaterialDialog.SingleButtonCallback() {
-        @Override
-        public void onClick(MaterialDialog dialog, DialogAction which) {
-            // TODO
-        }
-    })
-    .onNeutral(new MaterialDialog.SingleButtonCallback() {
-        @Override
-        public void onClick(MaterialDialog dialog, DialogAction which) {
-            // TODO
-        }
-    })
-    .onNegative(new MaterialDialog.SingleButtonCallback() {
-        @Override
-        public void onClick(MaterialDialog dialog, DialogAction which) {
-            // TODO
-        }
-    })
-    .onAny(new MaterialDialog.SingleButtonCallback() {
-        @Override
-        public void onClick(MaterialDialog dialog, DialogAction which) {
-            // TODO
-        }
-    });
-```
+### Plain
 
-If you are listening for all three action buttons, you could just use `onAny()`. The `which` (`DialogAction`)
- parameter will tell you which button was pressed.
+You can show lists using the `listItems` extension on `MaterialDialog`:
 
-If `autoDismiss` is turned off, then you must manually dismiss the dialog in these callbacks. Auto dismiss is on by default.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/basic_list.png" width="200px" />
 
----
-
-# CheckBox Prompts
-
-Checkbox prompts allow you to display a UI similar to what Android uses to ask for a permission on API 23+.
-
-**Note:** you can use checkbox prompts with list dialogs and input dialogs, too.
-
-```java
-new MaterialDialog.Builder(this)
-    .iconRes(R.drawable.ic_launcher)
-    .limitIconToDefaultSize()
-    .title(R.string.example_title)
-    .positiveText(R.string.allow)
-    .negativeText(R.string.deny)
-    .onAny(new MaterialDialog.SingleButtonCallback() {
-        @Override
-        public void onClick(MaterialDialog dialog, DialogAction which) {
-            showToast("Prompt checked? " + dialog.isPromptCheckBoxChecked());
-        }
-    })
-    .checkBoxPromptRes(R.string.dont_ask_again, false, null)
-    .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItems(R.array.socialNetworks)
+  .show()
 ```
 
----
+You can pass a literal string array too:
 
-# List Dialogs
-
-Creating a list dialog only requires passing in an array of strings. The callback (`itemsCallback`) is
-also very simple.
-
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .items(R.array.items)
-        .itemsCallback(new MaterialDialog.ListCallback() {
-            @Override
-            public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
-            }
-        })
-        .show();
-```
+```kotlin
+val myItems = arrayOf("Hello", "World")
 
-If `autoDismiss` is turned off, then you must manually dismiss the dialog in the callback. Auto dismiss is on by default.
-You can pass `positiveText()` or the other action buttons to the builder to force it to display the action buttons
-below your list, however this is only useful in some specific cases.
+MaterialDialog(this)
+  ...
+  .listItems(items = myItems)
+  .show()
+```
 
----
+To get item selection events, just append a lambda:
 
-# Single Choice List Dialogs
-
-Single choice list dialogs are almost identical to regular list dialogs. The only difference is that
-you use `itemsCallbackSingleChoice` to set a callback rather than `itemsCallback`. That signals the dialog to
-display radio buttons next to list items.
-
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .items(R.array.items)
-        .itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallbackSingleChoice() {
-            @Override
-            public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
-                /**
-                 * If you use alwaysCallSingleChoiceCallback(), which is discussed below,
-                 * returning false here won't allow the newly selected radio button to actually be selected.
-                 **/
-                return true;
-            }
-        })
-        .positiveText(R.string.choose)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItems(R.array.socialNetworks) { dialog, index, text ->
+    // Invoked when the user taps an item
+  }
+  .show()
 ```
 
-If you want to preselect an item, pass an index 0 or greater in place of -1 in `itemsCallbackSingleChoice()`.
-Later, you can update the selected index using `setSelectedIndex(int)` on the `MaterialDialog` instance,
-if you're not using a custom adapter.
+### Single Choice
 
-If you do not set a positive action button using `positiveText()`, the dialog will automatically call
-the single choice callback when user presses the positive action button. The dialog will also dismiss itself,
-unless auto dismiss is turned off.
+You can show single choice (radio button) lists using the `listItemsSingleChoice` extension 
+on `MaterialDialog`:
 
-If you make a call to `alwaysCallSingleChoiceCallback()`, the single choice callback will be called
-every time the user selects/unselects an item.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/single_choice_list.png" width="200px" />
 
-## Coloring Radio Buttons
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsSingleChoice(R.array.my_items) { _, index, text ->
+    // 
+  }
+  .show()
+```
 
-Like action buttons and many other elements of the Material dialog, you can customize the color of a 
- dialog's radio buttons. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
- `widgetColorAttr()`, and `choiceWidgetColor()` method. Their names and parameter annotations make them self explanatory.
+You can pass a literal string array too:
 
-`widgetColor` is the same color that affects other UI elements. `choiceWidgetColor` is specific to
-single and multiple choice dialogs, it only affects radio buttons and checkboxes. You provide a
-`ColorStateList` rather than a single color which is used to generate a `ColorStateList`.
+```kotlin
+val myItems = arrayOf("Hello", "World")
 
- Note that by default, radio buttons will be colored with the color held in `colorAccent` (for AppCompat)
- or `android:colorAccent` (for the Material theme) in your Activity's theme.
- 
-There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+MaterialDialog(this)
+  ...
+  .listItemsSingleChoice(items = myItems)
+  .show()
+```
 
 ---
 
-# Multi Choice List Dialogs
-
-Multiple choice list dialogs are almost identical to regular list dialogs. The only difference is that
-you use `itemsCallbackMultiChoice` to set a callback rather than `itemsCallback`. That signals the dialog to
-display check boxes next to list items, and the callback can return multiple selections.
-
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .items(R.array.items)
-        .itemsCallbackMultiChoice(null, new MaterialDialog.ListCallbackMultiChoice() {
-            @Override
-            public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text) {
-                /**
-                 * If you use alwaysCallMultiChoiceCallback(), which is discussed below,
-                 * returning false here won't allow the newly selected check box to actually be selected
-                 * (or the newly unselected check box to be unchecked).
-                 * See the limited multi choice dialog example in the sample project for details.
-                 **/
-                 return true;
-            }
-        })
-        .positiveText(R.string.choose)
-        .show();
-```
+If you want an option to be selected when the dialog opens, you can pass an `initialSelection` index):
 
-If you want to preselect any items, pass an array of indices (resource or literal) in place of null
-in `itemsCallbackMultiChoice()`. Later, you can update the selected indices using `setSelectedIndices(Integer[])`
-on the `MaterialDialog` instance, if you're not using a custom adapter.
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsSingleChoice(R.array.my_items, initialSelection = 1)
+  .show()
+```
 
-If you do not set a positive action button using `positiveText()`, the dialog will automatically call
-the multi choice callback when user presses the positive action button. The dialog will also dismiss itself,
-unless auto dismiss is turned off.
+To get item selection events, just append a lambda:
 
-If you make a call to `alwaysCallMultiChoiceCallback()`, the multi choice callback will be called
-every time the user selects/unselects an item.
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsSingleChoice(R.array.my_items) { dialog, index, text ->
+    // Invoked when the user selects an item
+  }
+  .show()
+```
 
-## Coloring Check Boxes
+Without action buttons, the selection callback is invoked immediately when the user taps an item. If
+you add a positive action button...
 
-Like action buttons and many other elements of the Material dialog, you can customize the color of a 
- dialog's check boxes. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
- `widgetColorAttr()`, and `choiceWidgetColor()` method. Their names and parameter annotations make them self explanatory.
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsSingleChoice(R.array.my_items) { dialog, index, text ->
+    // Invoked when the user selects an item
+  }
+  .positiveButton(R.string.select)
+  .show()
+```
 
-`widgetColor` is the same color that affects other UI elements. `choiceWidgetColor` is specific to
-single and multiple choice dialogs, it only affects radio buttons and checkboxes. You provide a
-`ColorStateList` rather than a single color which is used to generate a `ColorStateList`.
+...then the callback isn't invoked until the user selects an item *and* taps the positive action 
+button. You can override that behavior using the `waitForPositiveButton` argument.
 
- Note that by default, radio buttons will be colored with the color held in `colorAccent` (for AppCompat)
- or `android:colorAccent` (for the Material theme) in your Activity's theme.
- 
-There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+An added bonus, you can disable items from being selected/unselected:
 
----
+```kotlin
+val indices = intArrayOf(0, 2)
 
-# Assigning IDs to List Item Views
-
-If you need to keep track of list items by ID rather than index, you can assign item IDs from an integer array:
-
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.socialNetworks)
-        .items(R.array.socialNetworks)
-        .itemsIds(R.array.itemIds)
-        .itemsCallback(new MaterialDialog.ListCallback() {
-            @Override
-            public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
-                Toast.makeText(Activity.this, which + ": " + text + ", ID = " + view.getId(), Toast.LENGTH_SHORT).show();
-            }
-        })
-        .show();
+MaterialDialog(this)
+  ...
+  .listItemsSingleChoice(R.array.my_items, disabledIndices = indices)
+  .show()
 ```
 
-You can also pass a literal integer array (`int[]`) in place of an array resource ID.
+### Multiple Choice
 
----
-
-# Custom List Dialogs
+You can show multiple choice (checkbox) lists using the `listItemsMultiChoice` extension on `MaterialDialog`:
 
-Like Android's native dialogs, you can also pass in your own adapter via `.adapter()` to customize
-exactly how you want your list to work.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/multi_choice_list.png" width="200px" />
 
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.socialNetworks)
-         // second parameter is an optional layout manager. Must be a LinearLayoutManager or GridLayoutManager.
-        .adapter(new ButtonItemAdapter(this, R.array.socialNetworks), null)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsMultiChoice(R.array.my_items) { _, index, text ->
+    // 
+  }
+  .show()
 ```
 
-**Note** that with newer releases, Material Dialogs no longer supports `ListView` and `ListAdapter`.
-It's about time that everyone uses `RecyclerView`. **Your custom adapters will have to handle item click
-events on their own; this library's classes and sample project have some good examples of how that is done correctly.**
-
-If you need access to the `RecyclerView`, you can use the `MaterialDialog` instance:
-
-```java
-MaterialDialog dialog = new MaterialDialog.Builder(this)
-        ...
-        .build();
+You can pass a literal string array too:
 
-RecyclerView list = dialog.getRecyclerView();
-// Do something with it
+```kotlin
+val myItems = arrayOf("Hello", "World")
 
-dialog.show();
+MaterialDialog(this)
+  ...
+  .listItemsMultiChoice(items = myItems)
+  .show()
 ```
 
-Note that you don't need to be using a custom adapter in order to access the `RecyclerView`, it's there for single/multi choice dialogs, regular list dialogs, etc.
-
 ---
 
-# Custom Views
+If you want option(s) to be selected when the dialog opens, you can pass an `initialSelection` index):
 
-Custom views are very easy to implement.
+```kotlin
+val indices = intArrayOf(1, 3)
 
-```java
-boolean wrapInScrollView = true;
-new MaterialDialog.Builder(this)
-        .title(R.string.title)
-        .customView(R.layout.custom_view, wrapInScrollView)
-        .positiveText(R.string.positive)
-        .show();
+MaterialDialog(this)
+  ...
+  .listItemsMultiChoice(R.array.my_items, initialSelection = indices)
+  .show()
 ```
 
-If `wrapInScrollView` is true, then the library will place your custom view inside of a ScrollView for you.
-This allows users to scroll your custom view if necessary (small screens, long content, etc.). However, there are cases
-when you don't want that behavior. This mostly consists of cases when you'd have a ScrollView in your custom layout,
-including ListViews, RecyclerViews, WebViews, GridViews, etc. The sample project contains examples of using both true
- and false for this parameter.
-
-Your custom view will automatically have padding put around it when `wrapInScrollView` is true. Otherwise
-you're responsible for using padding values that look good with your content.
-
-## Later Access
-
-If you need to access a View in the custom view after the dialog is built, you can use `getCustomView()` of
-`MaterialDialog`. This is especially useful if you pass a layout resource to the `Builder`, the dialog will
-handle the view inflation for you.
+To get item selection events, just append a lambda:
 
-```java
-MaterialDialog dialog = //... initialization via the builder ...
-View view = dialog.getCustomView();
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsMultiChoice(R.array.my_items) { dialog, indices, items ->
+    // Invoked when the user selects an item
+  }
+  .show()
 ```
 
----
+Without action buttons, the selection callback is invoked immediately when the user taps an item. If
+you add a positive action button...
 
-# Typefaces
+```kotlin
+MaterialDialog(this)
+  ...
+  .listItemsMultiChoice(R.array.my_items) { dialog, indices, items ->
+    // Invoked when the user selects an item
+  }
+  .positiveButton(R.string.select)
+  .show()
+```
 
-If you want to use custom fonts, you can make a call to `typeface(String, String)` when
-using the `Builder`. This will pull fonts from files in your project's `assets/fonts` folder. For example,
-if you had `Roboto.ttf` and `Roboto-Light.ttf` in `/src/main/assets/fonts`, you would call `typeface("Roboto.ttf", "Roboto-Light.ttf")`.
-This method will also handle recycling Typefaces via the `TypefaceHelper` which you can use in your own project to avoid duplicate 
-allocations. The raw `typeface(Typeface, Typeface)` variation will not recycle typefaces, every call will allocate the Typeface again.
+...then the callback isn't invoked until the user select one or more items *and* taps the positive 
+action button. You can override that behavior using the `waitForPositiveButton` argument.
 
-There's a global theming attribute available to automatically apply fonts to every Material Dialog in
-your app, also.
+An added bonus, you can disable items from being selected/unselected:
 
----
+```kotlin
+val indices = intArrayOf(0, 2)
 
-# Getting and Setting Action Buttons
+MaterialDialog(this)
+  ...
+  .listItemsMultiChoice(R.array.my_items, disabledIndices = indices)
+  .show()
+```
 
-If you want to get a reference to one of the dialog action buttons after the dialog is built and shown (e.g. to enable or disable buttons):
+### Custom Adapters 
 
-```java
-MaterialDialog dialog = //... initialization via the builder ...
-View negative = dialog.getActionButton(DialogAction.NEGATIVE);
-View neutral = dialog.getActionButton(DialogAction.NEUTRAL);
-View positive = dialog.getActionButton(DialogAction.POSITIVE);
-```
+If you want to customize lists to use your own views, you need to use a custom adapter.
 
-If you want to update the title of a dialog action button (you can pass a string resource ID in place of the literal string, too):
+```kotlin
+val adapter: RecyclerView.Adapter<*> = // some sort of adapter implementation...
 
-```java
-MaterialDialog dialog = //... initialization via the builder ...
-dialog.setActionButton(DialogAction.NEGATIVE, "New Title");
+MaterialDialog(this)
+  .customListAdapter(adapter)
+  .show()
 ```
 
----
-
-# Theming
+A larger example won't be shown here, but check out the `files` module for an in-depth example.
 
-Before Lollipop, theming AlertDialogs was basically impossible without using reflection and custom drawables.
-Since KitKat, Android became more color neutral but AlertDialogs continued to use Holo Blue for the title and
-title divider. Lollipop has improved even more, with no colors in the dialog by default other than the action
-buttons. This library makes theming even easier.
+## Checkbox Prompts
 
-## Basics
+Checkbox prompts can be used together with any other dialog type, it gets shown in the same view
+which shows the action buttons.
 
-By default, Material Dialogs will apply a light theme or dark theme based on the `?android:textColorPrimary` 
-attribute retrieved from the context creating the dialog. If the color is light (e.g. more white), it will
-guess the Activity is using a dark theme and it will use the dialog's dark theme. Vice versa for the light theme. 
-You can manually set the theme used from the `Builder#theme()` method:
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/checkbox_prompt.png" width="200px" />
 
-```java
-new MaterialDialog.Builder(this)
-        .content("Hi")
-        .theme(Theme.DARK)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  checkBoxPrompt(R.string.your_label) { checked ->
+    // Check box was checked or unchecked
+  }
+  .show()
 ```
 
-Or you can use the global theming attribute, which is discussed in the section below. Global theming 
-avoids having to constantly call theme setters for every dialog you show.
-
-## Colors
-
-Pretty much every aspect of a dialog created with this library can be colored:
-
-```java
-new MaterialDialog.Builder(this)
-        .titleColorRes(R.color.material_red_500)
-        .contentColor(Color.WHITE) // notice no 'res' postfix for literal color
-        .linkColorAttr(R.attr.my_link_color_attr)  // notice attr is used instead of none or res for attribute resolving
-        .dividerColorRes(R.color.material_pink_500)
-        .backgroundColorRes(R.color.material_blue_grey_800)
-        .positiveColorRes(R.color.material_red_500)
-        .neutralColorRes(R.color.material_red_500)
-        .negativeColorRes(R.color.material_red_500)
-        .widgetColorRes(R.color.material_red_500)
-        .buttonRippleColorRes(R.color.material_red_500)
-        .show();
-```
+You can pass a literal string for the label too:
 
-The names are self explanatory for the most part. The `widgetColor` method, discussed in a few other
-sections of this tutorial, applies to progress bars, check boxes, and radio buttons. Also note that 
-each of these methods have 3 variations for setting a color directly, using color resources, and using 
-color attributes.
+```kotlin
+MaterialDialog(this)
+  ...
+  .checkBoxPrompt(text = "Hello, World")
+  .show()
+```
 
-## Selectors
+---
 
-Selectors are drawables that change state when pressed or focused.
+You can also append a lambda which gets invoked when the checkbox is checked or unchecked:
 
-```java
-new MaterialDialog.Builder(this)
-        .btnSelector(R.drawable.custom_btn_selector)
-        .btnSelector(R.drawable.custom_btn_selector_primary, DialogAction.POSITIVE)
-        .btnSelectorStacked(R.drawable.custom_btn_selector_stacked)
-        .listSelector(R.drawable.custom_list_and_stackedbtn_selector)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .checkBoxPrompt(text = "Hello, World") { checked -> }
+  .show()
 ```
 
-The first `btnSelector` line sets a selector drawable used for all action buttons. The second `btnSelector`
-line overwrites the drawable used only for the positive button. This results in the positive button having
-a different selector than the neutral and negative buttons. `btnSelectorStacked` sets a selector drawable
-used when the buttons become stacked, either because there's not enough room to fit them all on one line,
-or because you used `forceStacked(true)` on the `Builder`. `listSelector` is used for list items, when
-you are NOT using a custom adapter.
+If you only care about the checkbox state when the positive action button is pressed:
 
-***Note***: 
+```kotlin
+MaterialDialog(this)
+  ...
+  .checkBoxPrompt(R.string.your_label)
+  .positiveButton(R.string.button_text) { dialog ->
+      val isChecked = dialog.isCheckPromptChecked()
+      // do something
+  }
+  .show()
+```
 
-***An important note related to using custom action button selectors***: make sure your selector drawable references
-inset drawables like the default ones do - this is important for correct action button padding.
+## Custom Views
 
-## Gravity
+A lot of the included extensions use custom views, such as the color chooser dialog. There's also 
+a simple example in the sample project.
 
-It's probably unlikely you'd want to change gravity of elements in a dialog, but it's possible.
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/custom_view.png" width="200px" /> 
 
-```java
-new MaterialDialog.Builder(this)
-        .titleGravity(GravityEnum.CENTER)
-        .contentGravity(GravityEnum.CENTER)
-        .btnStackedGravity(GravityEnum.START)
-        .itemsGravity(GravityEnum.END)
-        .buttonsGravity(GravityEnum.END)
-        .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .customView(R.layout.my_custom_view)
+  .show()
 ```
 
-These are pretty self explanatory. `titleGravity` sets the gravity for the dialog title, `contentGravity`
-sets the gravity for the dialog content, `btnStackedGravity` sets the gravity for stacked action buttons, 
-`itemsGravity` sets the gravity for list items (when you're NOT using a custom adapter). 
-
-For, `buttonsGravity` refer to this:
-
-<table>
-<tr>
-<td><b>START (Default)</b></td>
-<td>Neutral</td>
-<td>Negative</td>
-<td>Positive</td>
-</tr>
-<tr>
-<td><b>CENTER</b></td>
-<td>Negative</td>
-<td>Neutral</td>
-<td>Positive</td>
-</tr>
-<tr>
-<td><b>END</b></td>
-<td>Positive</td>
-<td>Negative</td>
-<td>Neutral</td>
-</tr>
-</table>
-
-With no positive button, the negative button takes it's place except for with CENTER.
-
-## Material Palette
-
-To see colors that fit the Material design palette, see this page: http://www.google.com/design/spec/style/color.html#color-color-palette
+You can also pass a literal view:
 
----
-
-# Global Theming
+```kotlin
+val myView: View = // ...
 
-Most of the theming aspects discussed in the above section can be automatically applied to all dialogs
-you show from an Activity which has a theme containing any of these attributes:
+MaterialDialog(this)
+  ...
+  .customView(view = myView)
+  .show()
+```
 
-```xml
-<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+If your custom view may be taller than the dialog, you'll want to make it scrollable:
 
-    <!--
-        All dialogs will default to Theme.DARK with this set to true.
-    -->
-    <item name="md_dark_theme">true</item>
+```kotlin
+MaterialDialog(this)
+  ...
+  .customView(R.layout.my_custom_view, scrollable = true)
+  .show()
+```
 
-    <!--
-        This overrides the default dark or light dialog background color.
-        Note that if you use a dark color here, you should set md_dark_theme to
-        true so text and selectors look visible
-    -->
-    <item name="md_background_color">#37474F</item>
+For later access, you can use `dialog.getCustomView()`:
 
-    <!--
-        Applies an icon next to the title in all dialogs.
-    -->
-    <item name="md_icon">@drawable/ic_launcher</item>
+```kotlin
+val dialog = MaterialDialog(this)
+  ...
+  .customView(R.layout.my_custom_view, scrollable = true)
   
-    <!--
-        Limit icon to a max size.
-    -->
-    <attr name="md_icon_max_size" format="dimension" />
-    
-    <!--
-        Limit the icon to a default max size (48dp).
-    -->
-    <attr name="md_icon_limit_icon_to_default_size" format="boolean" />
-
-    <!--
-        By default, the title text color is derived from the
-        ?android:textColorPrimary system attribute.
-    -->
-    <item name="md_title_color">#E91E63</item>
-
-
-    <!--
-        By default, the content text color is derived from the
-        ?android:textColorSecondary system attribute.
-    -->
-    <item name="md_content_color">#9C27B0</item>
-
-    <!--
-        By default, the link color is derived from the colorAccent attribute 
-        of AppCompat or android:colorAccent attribute of the Material theme.
-    -->
-    <item name="md_link_color">#673AB7</item>
-
-    <!--
-        By default, the positive action text color is derived
-        from the colorAccent attribute of AppCompat or android:colorAccent
-        attribute of the Material theme.
-    -->
-    <item name="md_positive_color">#673AB7</item>
-
-    <!--
-        By default, the neutral action text color is derived
-        from the colorAccent attribute of AppCompat or android:colorAccent
-        attribute of the Material theme.
-    -->
-    <item name="md_neutral_color">#673AB7</item>
-
-    <!--
-        By default, the negative action text color is derived
-        from the colorAccent attribute of AppCompat or android:colorAccent
-        attribute of the Material theme.
-    -->
-    <item name="md_negative_color">#673AB7</item>
-
-    <!--
-        By default, a progress dialog's progress bar, check boxes, and radio buttons 
-        have a color that is derived from the colorAccent attribute of AppCompat or 
-        android:colorAccent attribute of the Material theme.
-    -->
-    <item name="md_widget_color">#673AB7</item>
-
-    <!--
-        By default, the list item text color is black for the light
-        theme and white for the dark theme.
-    -->
-    <item name="md_item_color">#9C27B0</item>
-
-    <!--
-        This overrides the color used for the top and bottom dividers used when
-        content is scrollable
-    -->
-    <item name="md_divider_color">#E91E63</item>
-
-    <!--
-        This overrides the color used for the ripple displayed on action buttons (Lollipop and above).
-        Defaults to the colorControlHighlight attribute from AppCompat OR the Material theme.
-    -->
-    <item name="md_btn_ripple_color">#E91E63</item>
-
-    <!--
-        This overrides the selector used on list items.
-    -->
-    <item name="md_list_selector">@drawable/selector</item>
-
-    <!--
-        This overrides the selector used on stacked action buttons.
-    -->
-    <item name="md_btn_stacked_selector">@drawable/selector</item>
-
-    <!--
-        This overrides the background selector used on the positive action button.
-    -->
-    <item name="md_btn_positive_selector">@drawable/selector</item>
-
-    <!--
-        This overrides the background selector used on the neutral action button.
-    -->
-    <item name="md_btn_neutral_selector">@drawable/selector</item>
-
-    <!--
-        This overrides the background selector used on the negative action button.
-    -->
-    <item name="md_btn_negative_selector">@drawable/selector</item>
-    
-    <!-- 
-        This sets the gravity used while displaying the dialog title, defaults to start.
-        Can be start, center, or end.
-    -->
-    <item name="md_title_gravity">start</item>
-    
-    <!-- 
-        This sets the gravity used while displaying the dialog content, defaults to start.
-        Can be start, center, or end.
-    -->
-    <item name="md_content_gravity">start</item>
-    
-    <!--
-        This sets the gravity used while displaying the list items (not including custom adapters), defaults to start.
-        Can be start, center, or end.
-    -->
-    <item name="md_items_gravity">start</item>
-    
-    <!--
-        This sets the gravity used while displaying the dialog action buttons, defaults to start.
-        
-        START (Default)    Neutral     Negative    Positive
-        CENTER:            Negative    Neutral     Positive
-        END:	           Positive    Negative    Neutral
-    -->
-    <item name="md_buttons_gravity">start</item>
-    
-    <!--
-        This sets the gravity used while displaying the stacked action buttons, defaults to end.
-        Can be start, center, or end.
-    -->
-    <item name="md_btnstacked_gravity">end</item>
-
-    <!--
-        The name of font in assets/fonts used on titles and action buttons
-        (null uses device default). E.g. [your-project]/app/main/assets/fonts/[medium]
-    -->
-    <item name="md_medium_font">Roboto-Medium.ttf</item>
-
-    <!--
-        The name of font in assets/fonts used everywhere else, like content and list items
-        (null uses device default). E.g. [your-project]/app/main/assets/fonts/[regular]
-    -->
-    <item name="md_regular_font">Roboto-Regular.ttf</item>
-
-</style>
+val customView = dialog.getCustomView()
+// Use the view instance, e.g. to set values or setup listeners
+  
+dialog.show()
 ```
 
-The action button color is also derived from the `android:colorAccent` attribute of the Material theme,
-or `colorAccent` attribute of the AppCompat Material theme as seen in the sample project. Manually setting
-the color will override that behavior.
+## Miscellaneous
 
----
+There are little details which are easy to miss. For an example, auto dismiss controls whether pressing 
+the action buttons or tapping a list item will automatically dismiss the dialog or not. By default, 
+it's turned on. You can disable it:
 
-# Show, Cancel, and Dismiss Callbacks
-
-You can directly setup show/cancel/dismiss listeners from the `Builder` rather than on the resulting
-`MaterialDialog` instance.
-
-Also note that the `Builder` has a `cancelable()` method that lets you disable dismissing the dialog
-when you tap outside the dialog window.
-
-```java
-new MaterialDialog.Builder(this)
-    .title("Use Google's Location Services?")
-    .content("Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.")
-    .positiveText("Agree")
-    .showListener(new DialogInterface.OnShowListener() {
-        @Override
-        public void onShow(DialogInterface dialog) {
-        }
-    })
-    .cancelListener(new DialogInterface.OnCancelListener() {
-        @Override
-        public void onCancel(DialogInterface dialog) {
-        }
-    })
-    .dismissListener(new DialogInterface.OnDismissListener() {
-        @Override
-        public void onDismiss(DialogInterface dialog) {
-        }
-    })
-    .show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .noAutoDismiss()
+  .show()
 ```
 
 ---
 
-# Input Dialogs
-
-An input dialog is pretty self explanatory, it retrieves input from the user of your application with
-an input field (EditText). You can also display content above the EditText if you desire.
-
-```java
-new MaterialDialog.Builder(this)
-        .title(R.string.input)
-        .content(R.string.input_content)
-        .inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)
-        .input(R.string.input_hint, R.string.input_prefill, new MaterialDialog.InputCallback() {
-            @Override
-            public void onInput(MaterialDialog dialog, CharSequence input) {
-                // Do something
-            }
-        }).show();
-```
+# Input
 
-The input dialog will automatically handle focusing the EditText and displaying the keyboard to allow
-the user to immediately enter input. When the dialog is closed, the keyboard will be automatically dismissed.
+## Gradle Dependency
 
-**Note that the dialog will force the positive action button to be visible, when it's pressed the input
-is submitted to the callback.**
+[ ![Input](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Ainput/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Ainput/_latestVersion)
 
-**Also Note that the call to `inputType()` is optional.**
+The `input` module contains extensions to the core module, such as a text input dialog.
 
-## Coloring the EditText
+```gradle
+dependencies {
+	
+    implementation 'com.afollestad.material-dialogs:input:2.0.0-alpha01'
+}
+```
 
-Like action buttons and many other elements of the Material dialog, you can customize the color of a
- input dialog's `EditText`. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
- and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
- Note that by default, EditTexts will be colored with the color held in `colorAccent` (for AppCompat)
- or `android:colorAccent` (for the Material theme) in your Activity's theme.
+## Text Input
 
-There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+### Basics
 
-## Limiting Input Length
+You can setup an input dialog using the `input` extension on `MaterialDialog`:
 
-The code below will show a little indicator in the input dialog that tells the user how many characters they've
-typed. If they type less than 2 characters, or more than 20, the dialog won't allow the input to be submitted.
-It will also color the input field and character counter in error color passed for the third parameter.
- 
-If you pass 0 for the min length, there will be no min length. If you pass -1 for the max length, there will
-be no max length. If you don't pass a third parameter at all, it will default to Material red. 
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/input.png" width="200px" />
 
-```java
-new MaterialDialog.Builder(this)
-    .title(R.string.input)
-    .inputRangeRes(2, 20, R.color.material_red_500)
-    .input(null, null, new MaterialDialog.InputCallback() {
-        @Override
-        public void onInput(MaterialDialog dialog, CharSequence input) {
-            // Do something
-        }
-    }).show();
+```kotlin
+MaterialDialog(this)
+  ...
+  .input()
+  .positiveButton(R.string.submit)
+  .show()
 ```
 
-*Note that `inputRangeRes(int, int, int)` takes a color resource ID for the third parameter, while
-`inputRange(int, int, int)` takes a literal color integer for the second parameter. You can use either one, or use
-the variation that doesn't take a third parameter at all.
+With a setup input dialog, you can retrieve the input field:
 
-## Custom Invalidation
-
-The easiest way to invalidate (enable or disable the EditText based on whether you think the input is acceptable)
-input dialogs is to call `alwaysCallInputCallback()` from the `Builder` so that the callback is invoked
-every time the user changes their input. From there, you can constantly check what they've typed. If you
-decide they shouldn't be able to submit that, you can disable the submit button using this from within the callback:
-
-```java
-dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
+```kotlin
+val dialog: MaterialDialog = // ...
+val inputField: EditText = dialog.getInputField()
 ```
 
 ---
 
-# Progress Dialogs
+You can append a lambda to receive a callback when the positive action button is pressed with 
+text entered: 
 
-This library allows you to display progress dialogs with Material design that even use your app's
-accent color to color the progress bars (if you use AppCompat to theme your app, or the Material theme on Lollipop).
+```kotlin
+MaterialDialog(this)
+  ...
+  .input { dialog, text ->
+      // Text submitted with the action button
+  }
+  .positiveButton(R.string.submit)
+  .show()
+```
 
-## Proguard
+If you set `waitForPositiveButton` to false, the callback is invoked every time the text field is
+modified:
 
-Normally, `ObjectAnimator` in the context it's used in this library (for custom progress drawables) would
-need special proguard rules so that certain elements aren't removed when your app is built in release mode.
-Luckily, AAR packages are allowed to specify proguard rules that get included in apps that depend on them.
-So you do not need to worry about including any Proguard rules in order to ensure progress bars behave well.
+```kotlin
+MaterialDialog(this)
+  ...
+  .input(waitForPositiveButton = false) { dialog, text -> 
+      // Text changed
+  }
+  .positiveButton(R.string.done)
+  .show()
+```
 
-## Indeterminate Progress Dialogs
+### Hints and Prefill
 
-This will display the classic progress dialog with a spinning circle, see the sample project to see it in action:
+You can set a hint to the input field, which is the gray faded text shown when the field is empty:
 
-```java
-new MaterialDialog.Builder(this)
-    .title(R.string.progress_dialog)
-    .content(R.string.please_wait)
-    .progress(true, 0)
-    .show();
+```kotlin
+MaterialDialog(this)
+  .input(hintRes = R.string.hint_text)
+  .show()
 ```
 
-## Determinate (Seek Bar) Progress Dialogs
-
-If a dialog is not indeterminate, it displays a horizontal progress bar that increases up until a max value.
-The comments in the code explain what this does.
-
-```java
-// Create and show a non-indeterminate dialog with a max value of 150
-// If the showMinMax parameter is true, a min/max ratio will be shown to the left of the seek bar.
-boolean showMinMax = true;
-MaterialDialog dialog = new MaterialDialog.Builder(this)
-    .title(R.string.progress_dialog)
-    .content(R.string.please_wait)
-    .progress(false, 150, showMinMax)
-    .show();
-
-// Loop until the dialog's progress value reaches the max (150)
-while (dialog.getCurrentProgress() != dialog.getMaxProgress()) {
-    // If the progress dialog is cancelled (the user closes it before it's done), break the loop
-    if (dialog.isCancelled()) break;
-    // Wait 50 milliseconds to simulate doing work that requires progress
-    try {
-        Thread.sleep(50);
-    } catch (InterruptedException e) {
-        break;
-    }
-    // Increment the dialog's progress by 1 after sleeping for 50ms
-    dialog.incrementProgress(1);
-}
+A literal string can be used as well:
 
-// When the loop exits, set the dialog content to a string that equals "Done"
-dialog.setContent(getString(R.string.done));
+```kotlin
+MaterialDialog(this)
+  .input(hint = "Your Hint Text")
+  .show()
 ```
 
-See the sample project for this dialog in action, with the addition of threading.
-
-## Make an Indeterminate Dialog Horizontal
+---
 
-By default, indeterminate progress dialogs use a circular progress indicator. From the `Builder`,
-you can tell the dialog that it needs to use a horizontal indicator when displaying an indeterminate progress
-dialog:
+You can also prefill the input field:
 
-```java
-new MaterialDialog.Builder(this)
-    .title(R.string.progress_dialog)
-    .content(R.string.please_wait)
-    .progress(true, 0)
-    .progressIndeterminateStyle(true)
-    .show();
+```kotlin
+MaterialDialog(this)
+  .input(prefillRes = R.string.prefill_text)
+  .show()
 ```
 
-## Coloring the Progress Bar
-
-Like action buttons and many other elements of the Material dialog, you can customize the color of a 
- progress dialog's progress bar. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
- and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
- Note that by default, progress bars will be colored with the color held in `colorAccent` (for AppCompat)
- or `android:colorAccent` (for the Material theme) in your Activity's theme.
- 
-There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
-
-## Custom Number and Progress Formats
-
-Like the stock `ProgressDialog`, you can format the progress min/max numbers and the percentage indicator
-of determinate dialogs.
-
-```java
-MaterialDialog dialog = new MaterialDialog.Builder(this)
-    .progress(false, 150, true)
-    ...
-    .progressNumberFormat("%1d/%2d")
-    .progressPercentFormat(NumberFormat.getPercentageInstance())
-    ...
-    .show();
+A literal string can be used as well:
+
+```kotlin
+MaterialDialog(this)
+  .input(prefill = "Prefilled text")
+  .show()
 ```
 
-The values passed above are the default.
+### Input Types
 
----
+You can apply input types to the input field, which modifies the keyboard type when the field is 
+focused on. This is just taken right from the Android framework, the input type gets applied 
+directly to the underlying `EditText`:
 
-# Tint Helper
+```kotlin
+val type = InputType.TYPE_CLASS_TEXT and 
+  InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
+  
+MaterialDialog(this)
+  .input(inputType = type)
+  .show()
+```
 
-You can use the `MDTintHelper` class to dynamically color check boxes, radio buttons, edit texts, and progress bars 
-(to get around not being able to change `styles.xml` at runtime). It is used in the library to dynamically color
-UI elements to match your set `widgetColor`.
+### Max Length
 
----
+You can set a max length which makes a character counter visible, and disables the positive action 
+button if the input length goes over that:
 
-# Misc
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/input_max_length.png" width="200px" />
 
-If you don't want the dialog to automatically be dismissed when an action button is pressed or when
-the user selects a list item:
+```kotlin
+MaterialDialog(this)
+  .input(maxLength = 8)
+  .positiveButton(R.string.submit)
+  .show()
+```
+
+### Custom Validation
 
-```java
-MaterialDialog dialog = new MaterialDialog.Builder(this)
-        // ... other initialization
-        .autoDismiss(false)
-        .show();
+You can do custom validation using the input listener. This example enforces that the input
+starts with the letter 'a':
+
+```kotlin
+MaterialDialog(this)
+  .input { dialog, text ->
+    val inputField = dialog.getInputField()!!
+    val isValid = text.startsWith("a", true)
+    
+    inputField.error = if (isValid) null else "Must start with an 'a'!"
+    dialog.setActionButtonEnabled(POSITIVE, isValid)
+  }
+  .positiveButton(R.string.submit)
+  .show()
 ```
 
 ---
 
-# Color Chooser Dialogs
-
-The Builder is used like this:
-
-```java
-// Pass a context, along with the title of the dialog
-new ColorChooserDialog.Builder(this, R.string.color_palette)
-    .titleSub(R.string.colors)  // title of dialog when viewing shades of a color
-    .accentMode(accent)  // when true, will display accent palette instead of primary palette
-    .doneButton(R.string.md_done_label)  // changes label of the done button
-    .cancelButton(R.string.md_cancel_label)  // changes label of the cancel button
-    .backButton(R.string.md_back_label)  // changes label of the back button
-    .preselect(accent ? accentPreselect : primaryPreselect)  // optionally preselects a color
-    .dynamicButtonColor(true)  // defaults to true, false will disable changing action buttons' color to currently selected color
-    .show(this); // an AppCompatActivity which implements ColorCallback
-```
+# Files
 
-The Activity/Fragment you show the dialog in must implement `ColorCallback`:
+## Gradle Dependency
 
-```java
-public class MyActivity implements ColorChooserDialog.ColorCallback {
+[ ![Files](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Afiles/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Afiles/_latestVersion)
 
-    // ...
+The `files` module contains extensions to the core module, such as a file and folder chooser.
 
-    @Override
-    public void onColorSelection(ColorChooserDialog dialog, @ColorInt int color) {
-        // TODO
-    }
+```gradle
+dependencies {
+	
+    implementation 'com.afollestad.material-dialogs:files:2.0.0-alpha01'
 }
 ```
 
----
+## File Choosers
 
-You can also specify custom colors to be displayed if you don't want to use the built-in primary or accent
-color palettes (which consist of the entire Material Design Color Palette):
-
-```java
-int[] primary = new int[] {
-    Color.parseColor("#F44336")
-};
-int[][] secondary = new int[][] {
-    new int[] { Color.parseColor("#EF5350"), Color.parseColor("#F44336"), Color.parseColor("#E53935") }
-};
-
-new ColorChooserDialog.Builder(this, R.string.color_palette)
-    .titleSub(R.string.colors)
-    .customColors(primary, secondary)
-    .show(this);
-```
+### Basics
+
+**Note:** File choosers require your app to have permission to `READ_EXTERNAL_STORAGE`, otherwise 
+directory listings will come back empty.
 
-The first parameter for primary colors can also take an array resource (`R.array.colors`), which can be
-seen in the sample project. If you pass `null` for the second parameter, there will be no sub levels displayed
-for top level colors.
+You create file choosers using the `fileChooser` extension on `MaterialDialog`:
 
-## Finding Visible Dialogs
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/file_chooser.png" width="200px" />
+
+```kotlin
+MaterialDialog(this)
+  .fileChooser { dialog, file -> 
+      // File selected
+  }
+  .show()
+```
 
-Since the `ColorChooserDialog` is a `DialogFragment`, it attaches to your Activity/Fragment through its `FragmentManager`.
-`ColorChooserDialog` has a utility method called `findVisible(AppCompatActivity, String)` that will
-find a visible color chooser if any is visible:
+It shows all files and folders, starting in the external storage directory. Tapping a file invokes 
+the callback and dismisses the dialog.
 
-```java
-ColorChooserDialog primary = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_PRIMARY);
+You can change the directory which is listed initially:
 
-ColorChooserDialog accent = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_ACCENT);
+```kotlin
+val initialFolder = File(getExternalStorageDirectory(), "Download")
 
-ColorChooserDialog custom = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_CUSTOM);
+MaterialDialog(this)
+  .fileChooser(initialDirectory = initialFolder) { dialog, file -> 
+      // File selected
+  }
+  .show()
 ```
 
-## User Color Input
+**If a positive action button exists, tapping a file will select it, but the callback isn't invoked 
+until the positive action button is pressed.**
 
-By default, color chooser dialogs allow the user to input a custom color using RGB sliders or a Hexadecimal input field.
-This can be disabled if you don't want users to be able to use it:
+### Filter
 
-```java
-new ColorChooserDialog.Builder(this, R.string.color_palette)
-    .allowUserColorInput(false)
-    .customButton(R.string.md_custom_label)
-    .presetsButton(R.string.md_presets_label)
-    .show(this);
-```
+A filter can be applied to only show the files and directories you wish to show:
 
-If you want the user to be able to input a custom color, but don't want them to be able to change transparency (alpha):
+```kotlin
+// show ALL folders, and files that start with the letter 'a'
+val myFilter: FileFilter = { it.isDirectory || it.nameWithoutExtension.startsWith("a", true) }
 
-```java
-new ColorChooserDialog.Builder(this, R.string.color_palette)
-    .allowUserColorInputAlpha(false)
-    .customButton(R.string.md_custom_label)
-    .presetsButton(R.string.md_presets_label)
-    .show(this);
+MaterialDialog(this)
+  .fileChooser(filter = myFilter) { dialog, file -> 
+      // File selected
+  }
+  .show()
 ```
 
----
-
-# Preference Dialogs
+### Empty Text
 
-Android's `EditTextPreference`, `ListPreference`, and `MultiSelectListPreference` allow you to associate a preference activity's settings
-with user input that's received through typing or selection. Material Dialogs includes `MaterialEditTextPreference`,
-`MaterialListPreference`, and `MaterialMultiSelectListPreference` classes that can be used in your preferences XML to automatically use Material-themed
-dialogs. See the sample project for details.
+Empty text is shown when a folder has no contents. You can configure the empty text label:
 
-By default, all of these preference classes will set their layout to `R.layout.md_preference_custom`. If you 
-don't want a default layout to be set, you can provide an attribute on the preferences in your XML:
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/file_emptytext.png" width="200px" />
 
-```
-app:useStockLayout="true"
+```kotlin
+MaterialDialog(this)
+  .fileChooser(emptyTextRes = R.string.custom_label) { dialog, file -> 
+      // File selected
+  }
+  .show()
 ```
 
----
+## Folder Choosers
+
+**Note:** Folder choosers require your app to have permission to `READ_EXTERNAL_STORAGE`, otherwise 
+directory listings will come back empty.
 
-# File Selector Dialogs
+Folder choosers are basically the same as file choosers, with a few minor differences: 1) only folders 
+are shown, even when a custom filter is applied. 2) the selection callback is never invoked on a 
+item click, it only gets invoked with the currently viewed folder when the positive action button 
+is pressed.
 
-The Builder is used like this:
+### Basics
 
-```java
-new FileChooserDialog.Builder(this)
-    .initialPath("/sdcard/Download")  // changes initial path, defaults to external storage directory
-    .mimeType("image/*") // Optional MIME type filter
-    .extensionsFilter(".png", ".jpg") // Optional extension filter, will override mimeType()
-    .tag("optional-identifier")
-    .goUpLabel("Up") // custom go up label, default label is "..."
-    .show(this); // an AppCompatActivity which implements FileCallback
+```kotlin
+MaterialDialog(this)
+  .folderChooser { dialog, folder -> 
+      // Folder selected
+  }
+  .show()
 ```
 
-The Activity/Fragment you show the dialog in must implement `FileCallback`:
+### Filter
 
-```java
-public class MyActivity implements FileChooserDialog.FileCallback {
+You can apply a filter like you can with the file chooser.
 
-    // ...
+```kotlin
+// show only folders that start with the letter 'a'
+val myFilter: FileFilter = { it.name.startsWith("a", true) }
 
-    @Override
-    public void onFileSelection(FileChooserDialog dialog, File file) {
-        // TODO
-        final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
-    }
-}
+MaterialDialog(this)
+  .folderChooser(filter = myFilter) { dialog, file -> 
+      // Folder selected
+  }
+  .show()
+``` 
+
+### Empty Text
+
+Empty text is shown when a folder has no contents. You can configure the empty text label:
+
+```kotlin
+MaterialDialog(this)
+  .fileChooser(emptyTextRes = R.string.custom_label) { dialog, file -> 
+      // File selected
+  }
+  .show()
 ```
 
 ---
 
-# Folder Selector Dialogs
+# Color
+
+## Gradle Dependency
+
+[ ![Color](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Acolor/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Acolor/_latestVersion)
 
-The Builder is used like this:
+The `color` module contains extensions to the core module, such as a color chooser.
 
-```java
-// Pass AppCompatActivity which implements FolderCallback
-new FolderChooserDialog.Builder(this)
-    .chooseButton(R.string.md_choose_label)  // changes label of the choose button
-    .initialPath("/sdcard/Download")  // changes initial path, defaults to external storage directory
-    .tag("optional-identifier")
-    .goUpLabel("Up") // custom go up label, default label is "..."
-    .show(this);
+```gradle
+dependencies {
+	
+    implementation 'com.afollestad.material-dialogs:color:2.0.0-alpha01'
+}
 ```
 
-The Activity/Fragment you show the dialog in must implement `FolderCallback`:
+## Color Choosers
 
-```java
-public class MyActivity implements FolderChooserDialog.FolderCallback {
+### Basics
 
-    // ...
+Color choosers show a simple grid of colors.
 
-    @Override
-    public void onFolderSelection(FolderChooserDialog dialog, File folder) {
-        // TODO
-        final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
-    }
-}
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/color_chooser.png" width="200px" />
+
+```kotlin
+val colors = intArrayOf(Color.RED, Color.GREEN, Color.BLUE)
+
+MaterialDialog(this)
+  .title(R.string.colors)
+  .colorChooser(colors) { dialog, color ->
+      // Use color integer
+  }
+  .positiveButton(R.string.select)
+  .show()
 ```
 
----
+You can specify an initial selection, which is just a color integer:
 
-Optionally, you can allow users to have the ability to create new folders from this dialog:
+```kotlin
+val colors = intArrayOf(Color.RED, Color.GREEN, Color.BLUE)
 
-```java
-new FolderChooserDialog.Builder(this)
-    .chooseButton(R.string.md_choose_label)  // changes label of the choose button
-    .initialPath("/sdcard/Download")  // changes initial path, defaults to external storage directory
-    .tag("optional-identifier")
-    .allowNewFolder(true, R.string.new_folder)  // pass 0 in the second parameter to use default button label
-    .show(this);
+MaterialDialog(this)
+  .title(R.string.colors)
+  .colorChooser(colors, initialSelection = Color.BLUE) { dialog, color ->
+      // Use color integer
+  }
+  .positiveButton(R.string.select)
+  .show()
 ```
 
----
+### Sub Colors
 
-# Simple List Dialogs
-
-Simple List Dialogs are a specific style of list dialogs taken from the Material Design Guidelines: https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
-
-This library's implementation is just a pre-made adapter that you can pass to the `MaterialDialog.Builder`.
-
-```java
-final MaterialSimpleListAdapter adapter = new MaterialSimpleListAdapter(new MaterialSimpleListAdapter.Callback() {
-    @Override
-    public void onMaterialListItemSelected(MaterialDialog dialog, int index, MaterialSimpleListItem item) {
-        // TODO
-    }
-});
-
-adapter.add(new MaterialSimpleListItem.Builder(this)
-    .content("username@gmail.com")
-    .icon(R.drawable.ic_account_circle)
-    .backgroundColor(Color.WHITE)
-    .build());
-adapter.add(new MaterialSimpleListItem.Builder(this)
-    .content("user02@gmail.com")
-    .icon(R.drawable.ic_account_circle)
-    .backgroundColor(Color.WHITE)
-    .build());
-adapter.add(new MaterialSimpleListItem.Builder(this)
-    .content(R.string.add_account)
-    .icon(R.drawable.ic_content_add)
-    .iconPaddingDp(8)
-    .build());
-
-new MaterialDialog.Builder(this)
-    .title(R.string.set_backup)
-    .adapter(adapter, null)
-    .show();
-```
+You can specify sub-colors, which are a level down from each top level color. The size of the top 
+level array must match the size of the sub-colors array.
 
----
+<img src="https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/color_chooser_sub.png" width="200px" />
+
+```kotlin
+val colors = intArrayOf(Color.RED, Color.GREEN, Color.BLUE) // size = 3
+val subColors = arrayOf( // size = 3
+  intArrayOf(Color.LIGHT_RED, Color.RED, Color.DARK_RED, Color.WHITE),
+  intArrayOf(Color.LIGHT_GREEN, Color.GREEN, Color.DARK_GREEN, Color.GRAY),
+  intArrayOf(Color.LIGHT_BLUE, Color.BLUE, Color.DARK_BLUE, Color.BLACK)
+)
+
+MaterialDialog(this)
+  .title(R.string.colors)
+  .colorChooser(colors, subColors = subColors) { dialog, color ->
+      // Use color integer
+  }
+  .positiveButton(R.string.select)
+  .show()
+```

+ 1339 - 0
README_OLD.md

@@ -0,0 +1,1339 @@
+# Material Dialogs (Pre version 2.0, deprecated)
+
+[ ![Core](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Acore/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Acore/_latestVersion)
+[ ![Commons](https://api.bintray.com/packages/drummer-aidan/maven/material-dialogs%3Acommons/images/download.svg) ](https://bintray.com/drummer-aidan/maven/material-dialogs%3Acommons/_latestVersion)
+[![Build Status](https://travis-ci.org/afollestad/material-dialogs.svg)](https://travis-ci.org/afollestad/material-dialogs)
+[![Codacy Badge](https://api.codacy.com/project/badge/Grade/0a4acc30a9ce440087f7688735359bb8)](https://www.codacy.com/app/drummeraidan_50/material-dialogs?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=afollestad/material-dialogs&amp;utm_campaign=Badge_Grade)
+[![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/afollestad/material-dialogs/blob/master/LICENSE.txt)
+
+![Screenshots](https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/readmeshowcase.png)
+
+# Table of Contents (Core)
+
+1. [Sample Project](https://github.com/afollestad/material-dialogs#sample-project)
+2. [Gradle Dependency](https://github.com/afollestad/material-dialogs#gradle-dependency)
+    1. [Repository](https://github.com/afollestad/material-dialogs#repository)
+    2. [Core](https://github.com/afollestad/material-dialogs#core)
+    3. [Commons](https://github.com/afollestad/material-dialogs#commons)
+3. [What's New](https://github.com/afollestad/material-dialogs#whats-new)
+4. [Basic Dialog](https://github.com/afollestad/material-dialogs#basic-dialog)
+5. [Dismissing Dialogs](https://github.com/afollestad/material-dialogs#dismissing-dialogs)
+6. [Displaying an Icon](https://github.com/afollestad/material-dialogs#displaying-an-icon)
+7. [Stacked Action Buttons](https://github.com/afollestad/material-dialogs#stacked-action-buttons)
+    1. [Stacking Behavior](https://github.com/afollestad/material-dialogs#stacking-behavior)
+8. [Neutral Action Button](https://github.com/afollestad/material-dialogs#neutral-action-button)
+9. [Callbacks](https://github.com/afollestad/material-dialogs#callbacks)
+10. [CheckBox Prompts](https://github.com/afollestad/material-dialogs#checkbox-prompts)
+11. [List Dialogs](https://github.com/afollestad/material-dialogs#list-dialogs)
+12. [Single Choice List Dialogs](https://github.com/afollestad/material-dialogs#single-choice-list-dialogs)
+    1. [Coloring Radio Buttons](https://github.com/afollestad/material-dialogs#coloring-radio-buttons)
+13. [Multi Choice List Dialogs](https://github.com/afollestad/material-dialogs#multi-choice-list-dialogs)
+    1. [Coloring Check Boxes](https://github.com/afollestad/material-dialogs#coloring-check-boxes)
+14. [Assigning IDs to List Item Views](https://github.com/afollestad/material-dialogs#assigning-ids-to-list-item-views)
+15. [Custom List Dialogs](https://github.com/afollestad/material-dialogs#custom-list-dialogs)
+16. [Custom Views](https://github.com/afollestad/material-dialogs#custom-views)
+    1. [Later Access](https://github.com/afollestad/material-dialogs#later-access)
+17. [Typefaces](https://github.com/afollestad/material-dialogs#typefaces)
+18. [Getting and Setting Action Buttons](https://github.com/afollestad/material-dialogs#getting-and-setting-action-buttons)
+19. [Theming](https://github.com/afollestad/material-dialogs#theming)
+    1. [Basics](https://github.com/afollestad/material-dialogs#basics)
+    2. [Colors](https://github.com/afollestad/material-dialogs#colors)
+    3. [Selectors](https://github.com/afollestad/material-dialogs#selectors)
+    4. [Gravity](https://github.com/afollestad/material-dialogs#gravity)
+    5. [Material Palette](https://github.com/afollestad/material-dialogs#material-palette)
+20. [Global Theming](https://github.com/afollestad/material-dialogs#global-theming)
+21. [Show, Cancel, and Dismiss Callbacks](https://github.com/afollestad/material-dialogs#show-cancel-and-dismiss-callbacks)
+22. [Input Dialogs](https://github.com/afollestad/material-dialogs#input-dialogs)
+    1. [Coloring the EditText](https://github.com/afollestad/material-dialogs#coloring-the-edittext)
+    2. [Limiting Input Length](https://github.com/afollestad/material-dialogs#limiting-input-length)
+    3. [Custom Invalidation](https://github.com/afollestad/material-dialogs#custom-invalidation)
+23. [Progress Dialogs](https://github.com/afollestad/material-dialogs#progress-dialogs)
+    1. [Proguard](https://github.com/afollestad/material-dialogs#proguard)
+    2. [Indeterminate Progress Dialogs](https://github.com/afollestad/material-dialogs#indeterminate-progress-dialogs)
+    3. [Determinate (Seek Bar) Progress Dialogs](https://github.com/afollestad/material-dialogs#determinate-seek-bar-progress-dialogs)
+    4. [Make an Indeterminate Dialog Horizontal](https://github.com/afollestad/material-dialogs#make-an-indeterminate-dialog-horizontal)
+    5. [Coloring the Progress Bar](https://github.com/afollestad/material-dialogs#coloring-the-progress-bar)
+    6. [Custom Number and Progress Formats](https://github.com/afollestad/material-dialogs#custom-number-and-progress-formats)
+24. [Tint Helper](https://github.com/afollestad/material-dialogs#tint-helper)
+25. [Misc](https://github.com/afollestad/material-dialogs#misc)
+
+# Table of Contents (Commons)
+
+1. [Color Chooser Dialogs](https://github.com/afollestad/material-dialogs#color-chooser-dialogs)
+    1. [Finding Visible Dialogs](https://github.com/afollestad/material-dialogs#finding-visible-dialogs)
+    2. [User Color Input](https://github.com/afollestad/material-dialogs#user-color-input)
+2. [File Selector Dialogs](https://github.com/afollestad/material-dialogs#file-selector-dialogs)
+3. [Folder Selector Dialogs](https://github.com/afollestad/material-dialogs#folder-selector-dialogs)
+4. [Preference Dialogs](https://github.com/afollestad/material-dialogs#preference-dialogs)
+5. [Simple List Dialogs](https://github.com/afollestad/material-dialogs#simple-list-dialogs) 
+
+------
+
+# Sample Project
+
+You can download the latest sample APK from this repo here: https://github.com/afollestad/material-dialogs/blob/master/sample/sample.apk
+
+It's also on Google Play:
+
+<a href="https://play.google.com/store/apps/details?id=com.afollestad.materialdialogssample" target="_blank">
+  <img alt="Get it on Google Play"
+       src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" height="60"/>
+</a>
+
+Having the sample project installed is a good way to be notified of new releases. Although Watching this 
+repository will allow GitHub to email you whenever I publish a release.
+
+---
+
+# Gradle Dependency
+
+### Repository
+
+The Gradle dependency is available via [jCenter](https://bintray.com/drummer-aidan/maven/material-dialogs:core/view).
+jCenter is the default Maven repository used by Android Studio.
+
+The minimum API level supported by this library is API 14.
+
+### Core
+
+The *core* module contains all the major classes of this library, including `MaterialDialog`.
+You can create basic, list, single/multi choice, progress, input, etc. dialogs with core.
+
+```gradle
+dependencies {
+	// ... other dependencies here
+    implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
+}
+```
+
+### Commons
+
+The *commons* module contains extensions to the library that not everyone may need. This includes the
+`ColorChooserDialog`, `FolderChooserDialog`, the Material `Preference` classes, and `MaterialSimpleListAdapter`/`MaterialSimpleListItem`.
+
+```gradle
+dependencies {
+    // ... other dependencies here
+    implementation 'com.afollestad.material-dialogs:commons:0.9.6.0'
+}
+```
+
+It's likely that new extensions will be added to commons later.
+
+---
+
+# What's New
+
+See the project's Releases page for a list of versions with their changelogs.
+
+### [View Releases](https://github.com/afollestad/material-dialogs/releases)
+
+If you Watch this repository, GitHub will send you an email every time I publish an update.
+
+---
+
+# Basic Dialog
+
+First of all, note that `MaterialDialog` extends `DialogBase`, which extends `android.app.Dialog`.
+
+Here's a basic example that mimics the dialog you see on Google's Material design guidelines
+(here: http://www.google.com/design/spec/components/dialogs.html#dialogs-usage). Note that you can
+always substitute literal strings and string resources for methods that take strings, the same goes
+for color resources (e.g. `titleColor` and `titleColorRes`).
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .negativeText(R.string.disagree)
+        .show();
+```
+
+**Your Activities need to inherit the AppCompat themes in order to work correctly with this library.**
+The Material dialog will automatically match the `positiveColor` (which is used on the positive action
+button) to the `colorAccent` attribute of your styles.xml theme.
+
+If the content is long enough, it will become scrollable and a divider will be displayed above the action buttons.
+
+---
+
+# Dismissing Dialogs
+
+I've had lots of issues asking how you dismiss a dialog. It works the same way that `AlertDialog` does, as
+both `AlertDialog` and `MaterialDialog` are an instance of `android.app.Dialog` (which is where `dismiss()`
+and `show()` come from). You cannot dismiss a dialog using it's `Builder`. You can only dismiss a
+dialog using the dialog itself.
+
+There's many ways you can get an instance of `MaterialDialog`. The two major ways are through the `show()` and `build()`
+methods of `MaterialDialog.Builder`.
+
+Through `show()`, which immediately shows the dialog and returns the visible dialog:
+
+```java
+MaterialDialog dialog = new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .show();
+```
+
+Through `build()`, which only builds the dialog but doesn't show it until you say so:
+
+```java
+MaterialDialog.Builder builder = new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree);
+
+MaterialDialog dialog = builder.build();
+dialog.show();
+```
+
+Once the dialog is shown, you can dismiss it:
+
+```java
+dialog.dismiss();
+```
+
+There are other various places where the `MaterialDialog` instance is given, such as in some callbacks
+ that are discussed in future sections below.
+
+---
+
+# Displaying an Icon
+
+MaterialDialog supports the display of an icon just like the stock AlertDialog; it will go to the left of the title.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .icon(R.drawable.icon)
+        .show();
+```
+
+You can limit the maximum size of the icon using the `limitIconToDefaultSize()`, `maxIconSize(int size)`,
+ or `maxIconSizeRes(int sizeRes)` Builder methods.
+
+---
+
+# Stacked Action Buttons
+
+If you have multiple action buttons that together are too wide to fit on one line, the dialog will stack the
+buttons to be vertically oriented.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.longer_positive)
+        .negativeText(R.string.negative)
+        .show();
+```
+
+### Stacking Behavior
+
+You can set stacking behavior from the `Builder`:
+
+```java
+new MaterialDialog.Builder(this)
+    ...
+    .stackingBehavior(StackingBehavior.ADAPTIVE)  // the default value
+    .show();
+```
+
+---
+
+# Neutral Action Button
+
+You can specify neutral text in addition to the positive and negative text. It will show the neutral
+action on the far left.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .negativeText(R.string.disagree)
+        .neutralText(R.string.more_info)
+        .show();
+```
+
+---
+
+# Callbacks
+
+**As of version 0.8.2.0, the `callback()` Builder method is deprecated in favor of the individual callback methods
+  discussed below. Earlier versions will still require use of `ButtonCallback`.**
+
+To know when the user selects an action button, you set callbacks:
+
+```java
+new MaterialDialog.Builder(this)
+    .onPositive(new MaterialDialog.SingleButtonCallback() {
+        @Override
+        public void onClick(MaterialDialog dialog, DialogAction which) {
+            // TODO
+        }
+    })
+    .onNeutral(new MaterialDialog.SingleButtonCallback() {
+        @Override
+        public void onClick(MaterialDialog dialog, DialogAction which) {
+            // TODO
+        }
+    })
+    .onNegative(new MaterialDialog.SingleButtonCallback() {
+        @Override
+        public void onClick(MaterialDialog dialog, DialogAction which) {
+            // TODO
+        }
+    })
+    .onAny(new MaterialDialog.SingleButtonCallback() {
+        @Override
+        public void onClick(MaterialDialog dialog, DialogAction which) {
+            // TODO
+        }
+    });
+```
+
+If you are listening for all three action buttons, you could just use `onAny()`. The `which` (`DialogAction`)
+ parameter will tell you which button was pressed.
+
+If `autoDismiss` is turned off, then you must manually dismiss the dialog in these callbacks. Auto dismiss is on by default.
+
+---
+
+# CheckBox Prompts
+
+Checkbox prompts allow you to display a UI similar to what Android uses to ask for a permission on API 23+.
+
+**Note:** you can use checkbox prompts with list dialogs and input dialogs, too.
+
+```java
+new MaterialDialog.Builder(this)
+    .iconRes(R.drawable.ic_launcher)
+    .limitIconToDefaultSize()
+    .title(R.string.example_title)
+    .positiveText(R.string.allow)
+    .negativeText(R.string.deny)
+    .onAny(new MaterialDialog.SingleButtonCallback() {
+        @Override
+        public void onClick(MaterialDialog dialog, DialogAction which) {
+            showToast("Prompt checked? " + dialog.isPromptCheckBoxChecked());
+        }
+    })
+    .checkBoxPromptRes(R.string.dont_ask_again, false, null)
+    .show();
+```
+
+---
+
+# List Dialogs
+
+Creating a list dialog only requires passing in an array of strings. The callback (`itemsCallback`) is
+also very simple.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .items(R.array.items)
+        .itemsCallback(new MaterialDialog.ListCallback() {
+            @Override
+            public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
+            }
+        })
+        .show();
+```
+
+If `autoDismiss` is turned off, then you must manually dismiss the dialog in the callback. Auto dismiss is on by default.
+You can pass `positiveText()` or the other action buttons to the builder to force it to display the action buttons
+below your list, however this is only useful in some specific cases.
+
+---
+
+# Single Choice List Dialogs
+
+Single choice list dialogs are almost identical to regular list dialogs. The only difference is that
+you use `itemsCallbackSingleChoice` to set a callback rather than `itemsCallback`. That signals the dialog to
+display radio buttons next to list items.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .items(R.array.items)
+        .itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallbackSingleChoice() {
+            @Override
+            public boolean onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
+                /**
+                 * If you use alwaysCallSingleChoiceCallback(), which is discussed below,
+                 * returning false here won't allow the newly selected radio button to actually be selected.
+                 **/
+                return true;
+            }
+        })
+        .positiveText(R.string.choose)
+        .show();
+```
+
+If you want to preselect an item, pass an index 0 or greater in place of -1 in `itemsCallbackSingleChoice()`.
+Later, you can update the selected index using `setSelectedIndex(int)` on the `MaterialDialog` instance,
+if you're not using a custom adapter.
+
+If you do not set a positive action button using `positiveText()`, the dialog will automatically call
+the single choice callback when user presses the positive action button. The dialog will also dismiss itself,
+unless auto dismiss is turned off.
+
+If you make a call to `alwaysCallSingleChoiceCallback()`, the single choice callback will be called
+every time the user selects/unselects an item.
+
+## Coloring Radio Buttons
+
+Like action buttons and many other elements of the Material dialog, you can customize the color of a 
+ dialog's radio buttons. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
+ `widgetColorAttr()`, and `choiceWidgetColor()` method. Their names and parameter annotations make them self explanatory.
+
+`widgetColor` is the same color that affects other UI elements. `choiceWidgetColor` is specific to
+single and multiple choice dialogs, it only affects radio buttons and checkboxes. You provide a
+`ColorStateList` rather than a single color which is used to generate a `ColorStateList`.
+
+ Note that by default, radio buttons will be colored with the color held in `colorAccent` (for AppCompat)
+ or `android:colorAccent` (for the Material theme) in your Activity's theme.
+ 
+There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+
+---
+
+# Multi Choice List Dialogs
+
+Multiple choice list dialogs are almost identical to regular list dialogs. The only difference is that
+you use `itemsCallbackMultiChoice` to set a callback rather than `itemsCallback`. That signals the dialog to
+display check boxes next to list items, and the callback can return multiple selections.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .items(R.array.items)
+        .itemsCallbackMultiChoice(null, new MaterialDialog.ListCallbackMultiChoice() {
+            @Override
+            public boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text) {
+                /**
+                 * If you use alwaysCallMultiChoiceCallback(), which is discussed below,
+                 * returning false here won't allow the newly selected check box to actually be selected
+                 * (or the newly unselected check box to be unchecked).
+                 * See the limited multi choice dialog example in the sample project for details.
+                 **/
+                 return true;
+            }
+        })
+        .positiveText(R.string.choose)
+        .show();
+```
+
+If you want to preselect any items, pass an array of indices (resource or literal) in place of null
+in `itemsCallbackMultiChoice()`. Later, you can update the selected indices using `setSelectedIndices(Integer[])`
+on the `MaterialDialog` instance, if you're not using a custom adapter.
+
+If you do not set a positive action button using `positiveText()`, the dialog will automatically call
+the multi choice callback when user presses the positive action button. The dialog will also dismiss itself,
+unless auto dismiss is turned off.
+
+If you make a call to `alwaysCallMultiChoiceCallback()`, the multi choice callback will be called
+every time the user selects/unselects an item.
+
+## Coloring Check Boxes
+
+Like action buttons and many other elements of the Material dialog, you can customize the color of a 
+ dialog's check boxes. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
+ `widgetColorAttr()`, and `choiceWidgetColor()` method. Their names and parameter annotations make them self explanatory.
+
+`widgetColor` is the same color that affects other UI elements. `choiceWidgetColor` is specific to
+single and multiple choice dialogs, it only affects radio buttons and checkboxes. You provide a
+`ColorStateList` rather than a single color which is used to generate a `ColorStateList`.
+
+ Note that by default, radio buttons will be colored with the color held in `colorAccent` (for AppCompat)
+ or `android:colorAccent` (for the Material theme) in your Activity's theme.
+ 
+There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+
+---
+
+# Assigning IDs to List Item Views
+
+If you need to keep track of list items by ID rather than index, you can assign item IDs from an integer array:
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.socialNetworks)
+        .items(R.array.socialNetworks)
+        .itemsIds(R.array.itemIds)
+        .itemsCallback(new MaterialDialog.ListCallback() {
+            @Override
+            public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
+                Toast.makeText(Activity.this, which + ": " + text + ", ID = " + view.getId(), Toast.LENGTH_SHORT).show();
+            }
+        })
+        .show();
+```
+
+You can also pass a literal integer array (`int[]`) in place of an array resource ID.
+
+---
+
+# Custom List Dialogs
+
+Like Android's native dialogs, you can also pass in your own adapter via `.adapter()` to customize
+exactly how you want your list to work.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.socialNetworks)
+         // second parameter is an optional layout manager. Must be a LinearLayoutManager or GridLayoutManager.
+        .adapter(new ButtonItemAdapter(this, R.array.socialNetworks), null)
+        .show();
+```
+
+**Note** that with newer releases, Material Dialogs no longer supports `ListView` and `ListAdapter`.
+It's about time that everyone uses `RecyclerView`. **Your custom adapters will have to handle item click
+events on their own; this library's classes and sample project have some good examples of how that is done correctly.**
+
+If you need access to the `RecyclerView`, you can use the `MaterialDialog` instance:
+
+```java
+MaterialDialog dialog = new MaterialDialog.Builder(this)
+        ...
+        .build();
+
+RecyclerView list = dialog.getRecyclerView();
+// Do something with it
+
+dialog.show();
+```
+
+Note that you don't need to be using a custom adapter in order to access the `RecyclerView`, it's there for single/multi choice dialogs, regular list dialogs, etc.
+
+---
+
+# Custom Views
+
+Custom views are very easy to implement.
+
+```java
+boolean wrapInScrollView = true;
+new MaterialDialog.Builder(this)
+        .title(R.string.title)
+        .customView(R.layout.custom_view, wrapInScrollView)
+        .positiveText(R.string.positive)
+        .show();
+```
+
+If `wrapInScrollView` is true, then the library will place your custom view inside of a ScrollView for you.
+This allows users to scroll your custom view if necessary (small screens, long content, etc.). However, there are cases
+when you don't want that behavior. This mostly consists of cases when you'd have a ScrollView in your custom layout,
+including ListViews, RecyclerViews, WebViews, GridViews, etc. The sample project contains examples of using both true
+ and false for this parameter.
+
+Your custom view will automatically have padding put around it when `wrapInScrollView` is true. Otherwise
+you're responsible for using padding values that look good with your content.
+
+## Later Access
+
+If you need to access a View in the custom view after the dialog is built, you can use `getCustomView()` of
+`MaterialDialog`. This is especially useful if you pass a layout resource to the `Builder`, the dialog will
+handle the view inflation for you.
+
+```java
+MaterialDialog dialog = //... initialization via the builder ...
+View view = dialog.getCustomView();
+```
+
+---
+
+# Typefaces
+
+If you want to use custom fonts, you can make a call to `typeface(String, String)` when
+using the `Builder`. This will pull fonts from files in your project's `assets/fonts` folder. For example,
+if you had `Roboto.ttf` and `Roboto-Light.ttf` in `/src/main/assets/fonts`, you would call `typeface("Roboto.ttf", "Roboto-Light.ttf")`.
+This method will also handle recycling Typefaces via the `TypefaceHelper` which you can use in your own project to avoid duplicate 
+allocations. The raw `typeface(Typeface, Typeface)` variation will not recycle typefaces, every call will allocate the Typeface again.
+
+There's a global theming attribute available to automatically apply fonts to every Material Dialog in
+your app, also.
+
+---
+
+# Getting and Setting Action Buttons
+
+If you want to get a reference to one of the dialog action buttons after the dialog is built and shown (e.g. to enable or disable buttons):
+
+```java
+MaterialDialog dialog = //... initialization via the builder ...
+View negative = dialog.getActionButton(DialogAction.NEGATIVE);
+View neutral = dialog.getActionButton(DialogAction.NEUTRAL);
+View positive = dialog.getActionButton(DialogAction.POSITIVE);
+```
+
+If you want to update the title of a dialog action button (you can pass a string resource ID in place of the literal string, too):
+
+```java
+MaterialDialog dialog = //... initialization via the builder ...
+dialog.setActionButton(DialogAction.NEGATIVE, "New Title");
+```
+
+---
+
+# Theming
+
+Before Lollipop, theming AlertDialogs was basically impossible without using reflection and custom drawables.
+Since KitKat, Android became more color neutral but AlertDialogs continued to use Holo Blue for the title and
+title divider. Lollipop has improved even more, with no colors in the dialog by default other than the action
+buttons. This library makes theming even easier.
+
+## Basics
+
+By default, Material Dialogs will apply a light theme or dark theme based on the `?android:textColorPrimary` 
+attribute retrieved from the context creating the dialog. If the color is light (e.g. more white), it will
+guess the Activity is using a dark theme and it will use the dialog's dark theme. Vice versa for the light theme. 
+You can manually set the theme used from the `Builder#theme()` method:
+
+```java
+new MaterialDialog.Builder(this)
+        .content("Hi")
+        .theme(Theme.DARK)
+        .show();
+```
+
+Or you can use the global theming attribute, which is discussed in the section below. Global theming 
+avoids having to constantly call theme setters for every dialog you show.
+
+## Colors
+
+Pretty much every aspect of a dialog created with this library can be colored:
+
+```java
+new MaterialDialog.Builder(this)
+        .titleColorRes(R.color.material_red_500)
+        .contentColor(Color.WHITE) // notice no 'res' postfix for literal color
+        .linkColorAttr(R.attr.my_link_color_attr)  // notice attr is used instead of none or res for attribute resolving
+        .dividerColorRes(R.color.material_pink_500)
+        .backgroundColorRes(R.color.material_blue_grey_800)
+        .positiveColorRes(R.color.material_red_500)
+        .neutralColorRes(R.color.material_red_500)
+        .negativeColorRes(R.color.material_red_500)
+        .widgetColorRes(R.color.material_red_500)
+        .buttonRippleColorRes(R.color.material_red_500)
+        .show();
+```
+
+The names are self explanatory for the most part. The `widgetColor` method, discussed in a few other
+sections of this tutorial, applies to progress bars, check boxes, and radio buttons. Also note that 
+each of these methods have 3 variations for setting a color directly, using color resources, and using 
+color attributes.
+
+## Selectors
+
+Selectors are drawables that change state when pressed or focused.
+
+```java
+new MaterialDialog.Builder(this)
+        .btnSelector(R.drawable.custom_btn_selector)
+        .btnSelector(R.drawable.custom_btn_selector_primary, DialogAction.POSITIVE)
+        .btnSelectorStacked(R.drawable.custom_btn_selector_stacked)
+        .listSelector(R.drawable.custom_list_and_stackedbtn_selector)
+        .show();
+```
+
+The first `btnSelector` line sets a selector drawable used for all action buttons. The second `btnSelector`
+line overwrites the drawable used only for the positive button. This results in the positive button having
+a different selector than the neutral and negative buttons. `btnSelectorStacked` sets a selector drawable
+used when the buttons become stacked, either because there's not enough room to fit them all on one line,
+or because you used `forceStacked(true)` on the `Builder`. `listSelector` is used for list items, when
+you are NOT using a custom adapter.
+
+***Note***: 
+
+***An important note related to using custom action button selectors***: make sure your selector drawable references
+inset drawables like the default ones do - this is important for correct action button padding.
+
+## Gravity
+
+It's probably unlikely you'd want to change gravity of elements in a dialog, but it's possible.
+
+```java
+new MaterialDialog.Builder(this)
+        .titleGravity(GravityEnum.CENTER)
+        .contentGravity(GravityEnum.CENTER)
+        .btnStackedGravity(GravityEnum.START)
+        .itemsGravity(GravityEnum.END)
+        .buttonsGravity(GravityEnum.END)
+        .show();
+```
+
+These are pretty self explanatory. `titleGravity` sets the gravity for the dialog title, `contentGravity`
+sets the gravity for the dialog content, `btnStackedGravity` sets the gravity for stacked action buttons, 
+`itemsGravity` sets the gravity for list items (when you're NOT using a custom adapter). 
+
+For, `buttonsGravity` refer to this:
+
+<table>
+<tr>
+<td><b>START (Default)</b></td>
+<td>Neutral</td>
+<td>Negative</td>
+<td>Positive</td>
+</tr>
+<tr>
+<td><b>CENTER</b></td>
+<td>Negative</td>
+<td>Neutral</td>
+<td>Positive</td>
+</tr>
+<tr>
+<td><b>END</b></td>
+<td>Positive</td>
+<td>Negative</td>
+<td>Neutral</td>
+</tr>
+</table>
+
+With no positive button, the negative button takes it's place except for with CENTER.
+
+## Material Palette
+
+To see colors that fit the Material design palette, see this page: http://www.google.com/design/spec/style/color.html#color-color-palette
+
+---
+
+# Global Theming
+
+Most of the theming aspects discussed in the above section can be automatically applied to all dialogs
+you show from an Activity which has a theme containing any of these attributes:
+
+```xml
+<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+
+    <!--
+        All dialogs will default to Theme.DARK with this set to true.
+    -->
+    <item name="md_dark_theme">true</item>
+
+    <!--
+        This overrides the default dark or light dialog background color.
+        Note that if you use a dark color here, you should set md_dark_theme to
+        true so text and selectors look visible
+    -->
+    <item name="md_background_color">#37474F</item>
+
+    <!--
+        Applies an icon next to the title in all dialogs.
+    -->
+    <item name="md_icon">@drawable/ic_launcher</item>
+  
+    <!--
+        Limit icon to a max size.
+    -->
+    <attr name="md_icon_max_size" format="dimension" />
+    
+    <!--
+        Limit the icon to a default max size (48dp).
+    -->
+    <attr name="md_icon_limit_icon_to_default_size" format="boolean" />
+
+    <!--
+        By default, the title text color is derived from the
+        ?android:textColorPrimary system attribute.
+    -->
+    <item name="md_title_color">#E91E63</item>
+
+
+    <!--
+        By default, the content text color is derived from the
+        ?android:textColorSecondary system attribute.
+    -->
+    <item name="md_content_color">#9C27B0</item>
+
+    <!--
+        By default, the link color is derived from the colorAccent attribute 
+        of AppCompat or android:colorAccent attribute of the Material theme.
+    -->
+    <item name="md_link_color">#673AB7</item>
+
+    <!--
+        By default, the positive action text color is derived
+        from the colorAccent attribute of AppCompat or android:colorAccent
+        attribute of the Material theme.
+    -->
+    <item name="md_positive_color">#673AB7</item>
+
+    <!--
+        By default, the neutral action text color is derived
+        from the colorAccent attribute of AppCompat or android:colorAccent
+        attribute of the Material theme.
+    -->
+    <item name="md_neutral_color">#673AB7</item>
+
+    <!--
+        By default, the negative action text color is derived
+        from the colorAccent attribute of AppCompat or android:colorAccent
+        attribute of the Material theme.
+    -->
+    <item name="md_negative_color">#673AB7</item>
+
+    <!--
+        By default, a progress dialog's progress bar, check boxes, and radio buttons 
+        have a color that is derived from the colorAccent attribute of AppCompat or 
+        android:colorAccent attribute of the Material theme.
+    -->
+    <item name="md_widget_color">#673AB7</item>
+
+    <!--
+        By default, the list item text color is black for the light
+        theme and white for the dark theme.
+    -->
+    <item name="md_item_color">#9C27B0</item>
+
+    <!--
+        This overrides the color used for the top and bottom dividers used when
+        content is scrollable
+    -->
+    <item name="md_divider_color">#E91E63</item>
+
+    <!--
+        This overrides the color used for the ripple displayed on action buttons (Lollipop and above).
+        Defaults to the colorControlHighlight attribute from AppCompat OR the Material theme.
+    -->
+    <item name="md_btn_ripple_color">#E91E63</item>
+
+    <!--
+        This overrides the selector used on list items.
+    -->
+    <item name="md_list_selector">@drawable/selector</item>
+
+    <!--
+        This overrides the selector used on stacked action buttons.
+    -->
+    <item name="md_btn_stacked_selector">@drawable/selector</item>
+
+    <!--
+        This overrides the background selector used on the positive action button.
+    -->
+    <item name="md_btn_positive_selector">@drawable/selector</item>
+
+    <!--
+        This overrides the background selector used on the neutral action button.
+    -->
+    <item name="md_btn_neutral_selector">@drawable/selector</item>
+
+    <!--
+        This overrides the background selector used on the negative action button.
+    -->
+    <item name="md_btn_negative_selector">@drawable/selector</item>
+    
+    <!-- 
+        This sets the gravity used while displaying the dialog title, defaults to start.
+        Can be start, center, or end.
+    -->
+    <item name="md_title_gravity">start</item>
+    
+    <!-- 
+        This sets the gravity used while displaying the dialog content, defaults to start.
+        Can be start, center, or end.
+    -->
+    <item name="md_content_gravity">start</item>
+    
+    <!--
+        This sets the gravity used while displaying the list items (not including custom adapters), defaults to start.
+        Can be start, center, or end.
+    -->
+    <item name="md_items_gravity">start</item>
+    
+    <!--
+        This sets the gravity used while displaying the dialog action buttons, defaults to start.
+        
+        START (Default)    Neutral     Negative    Positive
+        CENTER:            Negative    Neutral     Positive
+        END:	           Positive    Negative    Neutral
+    -->
+    <item name="md_buttons_gravity">start</item>
+    
+    <!--
+        This sets the gravity used while displaying the stacked action buttons, defaults to end.
+        Can be start, center, or end.
+    -->
+    <item name="md_btnstacked_gravity">end</item>
+
+    <!--
+        The name of font in assets/fonts used on titles and action buttons
+        (null uses device default). E.g. [your-project]/app/main/assets/fonts/[medium]
+    -->
+    <item name="md_medium_font">Roboto-Medium.ttf</item>
+
+    <!--
+        The name of font in assets/fonts used everywhere else, like content and list items
+        (null uses device default). E.g. [your-project]/app/main/assets/fonts/[regular]
+    -->
+    <item name="md_regular_font">Roboto-Regular.ttf</item>
+
+</style>
+```
+
+The action button color is also derived from the `android:colorAccent` attribute of the Material theme,
+or `colorAccent` attribute of the AppCompat Material theme as seen in the sample project. Manually setting
+the color will override that behavior.
+
+---
+
+# Show, Cancel, and Dismiss Callbacks
+
+You can directly setup show/cancel/dismiss listeners from the `Builder` rather than on the resulting
+`MaterialDialog` instance.
+
+Also note that the `Builder` has a `cancelable()` method that lets you disable dismissing the dialog
+when you tap outside the dialog window.
+
+```java
+new MaterialDialog.Builder(this)
+    .title("Use Google's Location Services?")
+    .content("Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.")
+    .positiveText("Agree")
+    .showListener(new DialogInterface.OnShowListener() {
+        @Override
+        public void onShow(DialogInterface dialog) {
+        }
+    })
+    .cancelListener(new DialogInterface.OnCancelListener() {
+        @Override
+        public void onCancel(DialogInterface dialog) {
+        }
+    })
+    .dismissListener(new DialogInterface.OnDismissListener() {
+        @Override
+        public void onDismiss(DialogInterface dialog) {
+        }
+    })
+    .show();
+```
+
+---
+
+# Input Dialogs
+
+An input dialog is pretty self explanatory, it retrieves input from the user of your application with
+an input field (EditText). You can also display content above the EditText if you desire.
+
+```java
+new MaterialDialog.Builder(this)
+        .title(R.string.input)
+        .content(R.string.input_content)
+        .inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD)
+        .input(R.string.input_hint, R.string.input_prefill, new MaterialDialog.InputCallback() {
+            @Override
+            public void onInput(MaterialDialog dialog, CharSequence input) {
+                // Do something
+            }
+        }).show();
+```
+
+The input dialog will automatically handle focusing the EditText and displaying the keyboard to allow
+the user to immediately enter input. When the dialog is closed, the keyboard will be automatically dismissed.
+
+**Note that the dialog will force the positive action button to be visible, when it's pressed the input
+is submitted to the callback.**
+
+**Also Note that the call to `inputType()` is optional.**
+
+## Coloring the EditText
+
+Like action buttons and many other elements of the Material dialog, you can customize the color of a
+ input dialog's `EditText`. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
+ and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
+ Note that by default, EditTexts will be colored with the color held in `colorAccent` (for AppCompat)
+ or `android:colorAccent` (for the Material theme) in your Activity's theme.
+
+There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+
+## Limiting Input Length
+
+The code below will show a little indicator in the input dialog that tells the user how many characters they've
+typed. If they type less than 2 characters, or more than 20, the dialog won't allow the input to be submitted.
+It will also color the input field and character counter in error color passed for the third parameter.
+ 
+If you pass 0 for the min length, there will be no min length. If you pass -1 for the max length, there will
+be no max length. If you don't pass a third parameter at all, it will default to Material red. 
+
+```java
+new MaterialDialog.Builder(this)
+    .title(R.string.input)
+    .inputRangeRes(2, 20, R.color.material_red_500)
+    .input(null, null, new MaterialDialog.InputCallback() {
+        @Override
+        public void onInput(MaterialDialog dialog, CharSequence input) {
+            // Do something
+        }
+    }).show();
+```
+
+*Note that `inputRangeRes(int, int, int)` takes a color resource ID for the third parameter, while
+`inputRange(int, int, int)` takes a literal color integer for the second parameter. You can use either one, or use
+the variation that doesn't take a third parameter at all.
+
+## Custom Invalidation
+
+The easiest way to invalidate (enable or disable the EditText based on whether you think the input is acceptable)
+input dialogs is to call `alwaysCallInputCallback()` from the `Builder` so that the callback is invoked
+every time the user changes their input. From there, you can constantly check what they've typed. If you
+decide they shouldn't be able to submit that, you can disable the submit button using this from within the callback:
+
+```java
+dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
+```
+
+---
+
+# Progress Dialogs
+
+This library allows you to display progress dialogs with Material design that even use your app's
+accent color to color the progress bars (if you use AppCompat to theme your app, or the Material theme on Lollipop).
+
+## Proguard
+
+Normally, `ObjectAnimator` in the context it's used in this library (for custom progress drawables) would
+need special proguard rules so that certain elements aren't removed when your app is built in release mode.
+Luckily, AAR packages are allowed to specify proguard rules that get included in apps that depend on them.
+So you do not need to worry about including any Proguard rules in order to ensure progress bars behave well.
+
+## Indeterminate Progress Dialogs
+
+This will display the classic progress dialog with a spinning circle, see the sample project to see it in action:
+
+```java
+new MaterialDialog.Builder(this)
+    .title(R.string.progress_dialog)
+    .content(R.string.please_wait)
+    .progress(true, 0)
+    .show();
+```
+
+## Determinate (Seek Bar) Progress Dialogs
+
+If a dialog is not indeterminate, it displays a horizontal progress bar that increases up until a max value.
+The comments in the code explain what this does.
+
+```java
+// Create and show a non-indeterminate dialog with a max value of 150
+// If the showMinMax parameter is true, a min/max ratio will be shown to the left of the seek bar.
+boolean showMinMax = true;
+MaterialDialog dialog = new MaterialDialog.Builder(this)
+    .title(R.string.progress_dialog)
+    .content(R.string.please_wait)
+    .progress(false, 150, showMinMax)
+    .show();
+
+// Loop until the dialog's progress value reaches the max (150)
+while (dialog.getCurrentProgress() != dialog.getMaxProgress()) {
+    // If the progress dialog is cancelled (the user closes it before it's done), break the loop
+    if (dialog.isCancelled()) break;
+    // Wait 50 milliseconds to simulate doing work that requires progress
+    try {
+        Thread.sleep(50);
+    } catch (InterruptedException e) {
+        break;
+    }
+    // Increment the dialog's progress by 1 after sleeping for 50ms
+    dialog.incrementProgress(1);
+}
+
+// When the loop exits, set the dialog content to a string that equals "Done"
+dialog.setContent(getString(R.string.done));
+```
+
+See the sample project for this dialog in action, with the addition of threading.
+
+## Make an Indeterminate Dialog Horizontal
+
+By default, indeterminate progress dialogs use a circular progress indicator. From the `Builder`,
+you can tell the dialog that it needs to use a horizontal indicator when displaying an indeterminate progress
+dialog:
+
+```java
+new MaterialDialog.Builder(this)
+    .title(R.string.progress_dialog)
+    .content(R.string.please_wait)
+    .progress(true, 0)
+    .progressIndeterminateStyle(true)
+    .show();
+```
+
+## Coloring the Progress Bar
+
+Like action buttons and many other elements of the Material dialog, you can customize the color of a 
+ progress dialog's progress bar. The `Builder` class contains a `widgetColor()`, `widgetColorRes()`,
+ and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
+ Note that by default, progress bars will be colored with the color held in `colorAccent` (for AppCompat)
+ or `android:colorAccent` (for the Material theme) in your Activity's theme.
+ 
+There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
+
+## Custom Number and Progress Formats
+
+Like the stock `ProgressDialog`, you can format the progress min/max numbers and the percentage indicator
+of determinate dialogs.
+
+```java
+MaterialDialog dialog = new MaterialDialog.Builder(this)
+    .progress(false, 150, true)
+    ...
+    .progressNumberFormat("%1d/%2d")
+    .progressPercentFormat(NumberFormat.getPercentageInstance())
+    ...
+    .show();
+```
+
+The values passed above are the default.
+
+---
+
+# Tint Helper
+
+You can use the `MDTintHelper` class to dynamically color check boxes, radio buttons, edit texts, and progress bars 
+(to get around not being able to change `styles.xml` at runtime). It is used in the library to dynamically color
+UI elements to match your set `widgetColor`.
+
+---
+
+# Misc
+
+If you don't want the dialog to automatically be dismissed when an action button is pressed or when
+the user selects a list item:
+
+```java
+MaterialDialog dialog = new MaterialDialog.Builder(this)
+        // ... other initialization
+        .autoDismiss(false)
+        .show();
+```
+
+---
+
+# Color Chooser Dialogs
+
+The Builder is used like this:
+
+```java
+// Pass a context, along with the title of the dialog
+new ColorChooserDialog.Builder(this, R.string.color_palette)
+    .titleSub(R.string.colors)  // title of dialog when viewing shades of a color
+    .accentMode(accent)  // when true, will display accent palette instead of primary palette
+    .doneButton(R.string.md_done_label)  // changes label of the done button
+    .cancelButton(R.string.md_cancel_label)  // changes label of the cancel button
+    .backButton(R.string.md_back_label)  // changes label of the back button
+    .preselect(accent ? accentPreselect : primaryPreselect)  // optionally preselects a color
+    .dynamicButtonColor(true)  // defaults to true, false will disable changing action buttons' color to currently selected color
+    .show(this); // an AppCompatActivity which implements ColorCallback
+```
+
+The Activity/Fragment you show the dialog in must implement `ColorCallback`:
+
+```java
+public class MyActivity implements ColorChooserDialog.ColorCallback {
+
+    // ...
+
+    @Override
+    public void onColorSelection(ColorChooserDialog dialog, @ColorInt int color) {
+        // TODO
+    }
+}
+```
+
+---
+
+You can also specify custom colors to be displayed if you don't want to use the built-in primary or accent
+color palettes (which consist of the entire Material Design Color Palette):
+
+```java
+int[] primary = new int[] {
+    Color.parseColor("#F44336")
+};
+int[][] secondary = new int[][] {
+    new int[] { Color.parseColor("#EF5350"), Color.parseColor("#F44336"), Color.parseColor("#E53935") }
+};
+
+new ColorChooserDialog.Builder(this, R.string.color_palette)
+    .titleSub(R.string.colors)
+    .customColors(primary, secondary)
+    .show(this);
+```
+
+The first parameter for primary colors can also take an array resource (`R.array.colors`), which can be
+seen in the sample project. If you pass `null` for the second parameter, there will be no sub levels displayed
+for top level colors.
+
+## Finding Visible Dialogs
+
+Since the `ColorChooserDialog` is a `DialogFragment`, it attaches to your Activity/Fragment through its `FragmentManager`.
+`ColorChooserDialog` has a utility method called `findVisible(AppCompatActivity, String)` that will
+find a visible color chooser if any is visible:
+
+```java
+ColorChooserDialog primary = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_PRIMARY);
+
+ColorChooserDialog accent = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_ACCENT);
+
+ColorChooserDialog custom = ColorChooserDialog.findVisible(getSupportFragmentManager(), ColorChooserDialog.TAG_CUSTOM);
+```
+
+## User Color Input
+
+By default, color chooser dialogs allow the user to input a custom color using RGB sliders or a Hexadecimal input field.
+This can be disabled if you don't want users to be able to use it:
+
+```java
+new ColorChooserDialog.Builder(this, R.string.color_palette)
+    .allowUserColorInput(false)
+    .customButton(R.string.md_custom_label)
+    .presetsButton(R.string.md_presets_label)
+    .show(this);
+```
+
+If you want the user to be able to input a custom color, but don't want them to be able to change transparency (alpha):
+
+```java
+new ColorChooserDialog.Builder(this, R.string.color_palette)
+    .allowUserColorInputAlpha(false)
+    .customButton(R.string.md_custom_label)
+    .presetsButton(R.string.md_presets_label)
+    .show(this);
+```
+
+---
+
+# Preference Dialogs
+
+Android's `EditTextPreference`, `ListPreference`, and `MultiSelectListPreference` allow you to associate a preference activity's settings
+with user input that's received through typing or selection. Material Dialogs includes `MaterialEditTextPreference`,
+`MaterialListPreference`, and `MaterialMultiSelectListPreference` classes that can be used in your preferences XML to automatically use Material-themed
+dialogs. See the sample project for details.
+
+By default, all of these preference classes will set their layout to `R.layout.md_preference_custom`. If you 
+don't want a default layout to be set, you can provide an attribute on the preferences in your XML:
+
+```
+app:useStockLayout="true"
+```
+
+---
+
+# File Selector Dialogs
+
+The Builder is used like this:
+
+```java
+new FileChooserDialog.Builder(this)
+    .initialPath("/sdcard/Download")  // changes initial path, defaults to external storage directory
+    .mimeType("image/*") // Optional MIME type filter
+    .extensionsFilter(".png", ".jpg") // Optional extension filter, will override mimeType()
+    .tag("optional-identifier")
+    .goUpLabel("Up") // custom go up label, default label is "..."
+    .show(this); // an AppCompatActivity which implements FileCallback
+```
+
+The Activity/Fragment you show the dialog in must implement `FileCallback`:
+
+```java
+public class MyActivity implements FileChooserDialog.FileCallback {
+
+    // ...
+
+    @Override
+    public void onFileSelection(FileChooserDialog dialog, File file) {
+        // TODO
+        final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
+    }
+}
+```
+
+---
+
+# Folder Selector Dialogs
+
+The Builder is used like this:
+
+```java
+// Pass AppCompatActivity which implements FolderCallback
+new FolderChooserDialog.Builder(this)
+    .chooseButton(R.string.md_choose_label)  // changes label of the choose button
+    .initialPath("/sdcard/Download")  // changes initial path, defaults to external storage directory
+    .tag("optional-identifier")
+    .goUpLabel("Up") // custom go up label, default label is "..."
+    .show(this);
+```
+
+The Activity/Fragment you show the dialog in must implement `FolderCallback`:
+
+```java
+public class MyActivity implements FolderChooserDialog.FolderCallback {
+
+    // ...
+
+    @Override
+    public void onFolderSelection(FolderChooserDialog dialog, File folder) {
+        // TODO
+        final String tag = dialog.getTag(); // gets tag set from Builder, if you use multiple dialogs
+    }
+}
+```
+
+---
+
+Optionally, you can allow users to have the ability to create new folders from this dialog:
+
+```java
+new FolderChooserDialog.Builder(this)
+    .chooseButton(R.string.md_choose_label)  // changes label of the choose button
+    .initialPath("/sdcard/Download")  // changes initial path, defaults to external storage directory
+    .tag("optional-identifier")
+    .allowNewFolder(true, R.string.new_folder)  // pass 0 in the second parameter to use default button label
+    .show(this);
+```
+
+---
+
+# Simple List Dialogs
+
+Simple List Dialogs are a specific style of list dialogs taken from the Material Design Guidelines: https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
+
+This library's implementation is just a pre-made adapter that you can pass to the `MaterialDialog.Builder`.
+
+```java
+final MaterialSimpleListAdapter adapter = new MaterialSimpleListAdapter(new MaterialSimpleListAdapter.Callback() {
+    @Override
+    public void onMaterialListItemSelected(MaterialDialog dialog, int index, MaterialSimpleListItem item) {
+        // TODO
+    }
+});
+
+adapter.add(new MaterialSimpleListItem.Builder(this)
+    .content("username@gmail.com")
+    .icon(R.drawable.ic_account_circle)
+    .backgroundColor(Color.WHITE)
+    .build());
+adapter.add(new MaterialSimpleListItem.Builder(this)
+    .content("user02@gmail.com")
+    .icon(R.drawable.ic_account_circle)
+    .backgroundColor(Color.WHITE)
+    .build());
+adapter.add(new MaterialSimpleListItem.Builder(this)
+    .content(R.string.add_account)
+    .icon(R.drawable.ic_content_add)
+    .iconPaddingDp(8)
+    .build());
+
+new MaterialDialog.Builder(this)
+    .title(R.string.set_backup)
+    .adapter(adapter, null)
+    .show();
+```
+
+---


BIN
art/basic_list.png


BIN
art/basic_with_buttons.png


BIN
art/checkbox_prompt.png


BIN
art/color_chooser.png


BIN
art/color_chooser_sub.png


BIN
art/custom_view.png


BIN
art/file_chooser.png


BIN
art/file_emptytext.png




BIN
art/input_max_length.png


BIN
art/multi_choice_list.png


BIN
art/readmeshowcase.png


BIN
art/showcase20.jpg


BIN
art/single_choice_list.png


BIN
art/stacked_buttons.png


+ 26 - 0
bintrayconfig.gradle

@@ -0,0 +1,26 @@
+if (!project.rootProject.file('local.properties').exists()) {
+  println "Not applying install.gradle"
+  return
+}
+
+if (shard == null) {
+  throw new IllegalStateException("Must specify a shard in module's build.gradle")
+} else if (versions == null || versions.publishVersion == null) {
+  throw new IllegalStateException("Unable to reference publishVersion")
+}
+
+Properties properties = new Properties()
+properties.load(project.rootProject.file('local.properties').newDataInputStream())
+
+publish {
+  bintrayUser = properties.getProperty("bintray.user")
+  bintrayKey = properties.getProperty("bintray.apikey")
+  userOrg = 'drummer-aidan'
+  groupId = 'com.afollestad.material-dialogs'
+  uploadName = "material-dialogs:$shard"
+  artifactId = shard
+  publishVersion = versions.publishVersion
+  desc = 'A beautiful, fluid, and customizable dialogs API.'
+  website = 'https://github.com/afollestad/material-dialogs'
+  dryRun = false
+}

+ 22 - 31
build.gradle

@@ -1,39 +1,30 @@
-apply from: './gradle/dependencies.gradle'
+apply from: './dependencies.gradle'
+apply plugin: "com.github.ben-manes.versions"
 
 buildscript {
-    apply from: './gradle/dependencies.gradle'
+  apply from: './dependencies.gradle'
 
-    repositories {
-        jcenter()
-        google()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:' + versions.gradlePlugin
-        classpath 'com.diffplug.spotless:spotless-plugin-gradle:' + versions.spotlessPlugin
-        classpath 'com.novoda:bintray-release:' + versions.bintrayRelease
-        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:' + versions.kotlin
-    }
+  repositories {
+    google()
+    jcenter()
+  }
+
+  dependencies {
+    classpath 'com.android.tools.build:gradle:' + versions.gradlePlugin
+    classpath 'com.diffplug.spotless:spotless-plugin-gradle:' + versions.spotlessPlugin
+    classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:' + versions.kotlin
+    classpath 'com.github.ben-manes:gradle-versions-plugin:' + versions.versionPlugin
+    classpath 'com.novoda:bintray-release:' + versions.bintrayPlugin
+  }
 }
 
 allprojects {
-    repositories {
-        jcenter()
-        google()
-    }
+  repositories {
+    google()
+    jcenter()
+  }
 
-    buildscript {
-        repositories {
-            maven { url "https://plugins.gradle.org/m2/" }
-        }
-    }
-    apply plugin: "com.diffplug.gradle.spotless"
-    spotless {
-        java {
-            target "**/*.java"
-            trimTrailingWhitespace()
-            removeUnusedImports()
-            googleJavaFormat()
-            endWithNewline()
-        }
-    }
+  tasks.withType(Javadoc).all {
+    enabled = false
+  }
 }

+ 0 - 0
commons/.gitignore → color/.gitignore


+ 38 - 0
color/build.gradle

@@ -0,0 +1,38 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply from: '../dependencies.gradle'
+apply plugin: "com.github.ben-manes.versions"
+
+if (project.rootProject.file('local.properties').exists()) {
+  apply plugin: 'com.novoda.bintray-release'
+}
+
+android {
+  compileSdkVersion versions.compileSdk
+  buildToolsVersion versions.buildTools
+
+  defaultConfig {
+    minSdkVersion versions.minSdk
+    targetSdkVersion versions.compileSdk
+    versionCode versions.publishVersionCode
+    versionName versions.publishVersion
+  }
+
+  sourceSets {
+    main.res.srcDirs = [
+        'src/main/res',
+        'src/main/res-public'
+    ]
+  }
+}
+
+dependencies {
+  implementation 'com.android.support:recyclerview-v7:' + versions.supportLib
+  implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:' + versions.kotlin
+  implementation project(':core')
+}
+
+apply from: '../spotless.gradle'
+
+ext.shard = 'color'
+apply from: '../bintrayconfig.gradle'

+ 21 - 0
color/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 2 - 0
color/src/main/AndroidManifest.xml

@@ -0,0 +1,2 @@
+<manifest
+    package="com.afollestad.materialdialogs.color"/>

+ 77 - 0
color/src/main/java/com/afollestad/materialdialogs/color/ColorCircleView.kt

@@ -0,0 +1,77 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+package com.afollestad.materialdialogs.color
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Paint.Style.FILL
+import android.graphics.Paint.Style.STROKE
+import android.support.annotation.ColorInt
+import android.util.AttributeSet
+import android.view.View
+import com.afollestad.materialdialogs.color.utilext.dimenPx
+
+/** @author Aidan Follestad (afollestad) */
+internal class ColorCircleView(
+  context: Context,
+  attrs: AttributeSet? = null
+) : View(context, attrs) {
+
+  private val strokePaint = Paint()
+  private val fillPaint = Paint()
+
+  private val borderWidth = dimenPx(R.dimen.color_circle_view_border)
+
+  init {
+    setWillNotDraw(false)
+    strokePaint.style = STROKE
+    strokePaint.isAntiAlias = true
+    strokePaint.color = Color.BLACK
+    strokePaint.strokeWidth = borderWidth.toFloat()
+    fillPaint.style = FILL
+    fillPaint.isAntiAlias = true
+    fillPaint.color = Color.DKGRAY
+  }
+
+  @ColorInt
+  var color: Int = Color.BLACK
+    set(value) {
+      field = value
+      fillPaint.color = value
+      invalidate()
+    }
+  @ColorInt
+  var border: Int = Color.DKGRAY
+    set(value) {
+      field = value
+      strokePaint.color = value
+      invalidate()
+    }
+
+  override fun onMeasure(
+    widthMeasureSpec: Int,
+    heightMeasureSpec: Int
+  ) = super.onMeasure(widthMeasureSpec, widthMeasureSpec)
+
+  override fun onDraw(canvas: Canvas) {
+    super.onDraw(canvas)
+    canvas.drawCircle(
+        measuredWidth / 2f,
+        measuredHeight / 2f,
+        (measuredWidth / 2f) - borderWidth,
+        fillPaint
+    )
+    canvas.drawCircle(
+        measuredWidth / 2f,
+        measuredHeight / 2f,
+        (measuredWidth / 2f) - borderWidth,
+        strokePaint
+    )
+  }
+}

+ 173 - 0
color/src/main/java/com/afollestad/materialdialogs/color/ColorGridAdapter.kt

@@ -0,0 +1,173 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+package com.afollestad.materialdialogs.color
+
+import android.R.attr
+import android.support.annotation.ColorInt
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.OnClickListener
+import android.view.ViewGroup
+import android.widget.ImageView
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.WhichButton.POSITIVE
+import com.afollestad.materialdialogs.actions.hasActionButtons
+import com.afollestad.materialdialogs.actions.setActionButtonEnabled
+import com.afollestad.materialdialogs.color.utilext.getColor
+import com.afollestad.materialdialogs.color.utilext.isColorDark
+import com.afollestad.materialdialogs.color.utilext.setVisibleOrGone
+
+internal class ColorGridViewHolder(
+  itemView: View,
+  private val adapter: ColorGridAdapter
+) : RecyclerView.ViewHolder(itemView), OnClickListener {
+
+  init {
+    itemView.setOnClickListener(this)
+  }
+
+  val colorCircle: ColorCircleView? = itemView.findViewById(R.id.color_view)
+  val iconView: ImageView = itemView.findViewById(R.id.icon)
+
+  override fun onClick(view: View) = adapter.itemSelected(adapterPosition)
+}
+
+/** @author Aidan Follestad (afollestad */
+internal class ColorGridAdapter(
+  private val dialog: MaterialDialog,
+  private val colors: IntArray,
+  private val subColors: Array<IntArray>?,
+  @ColorInt private val initialSelection: Int?,
+  private val waitForPositiveButton: Boolean,
+  private val callback: ColorCallback
+) : RecyclerView.Adapter<ColorGridViewHolder>() {
+
+  private val upIcon =
+    if (getColor(dialog.windowContext, attr = attr.textColorPrimary).isColorDark())
+      R.drawable.icon_back_black
+    else R.drawable.icon_back_white
+
+  private var selectedTopIndex: Int = -1
+  private var selectedSubIndex: Int = -1
+  private var inSub: Boolean = false
+
+  internal fun itemSelected(index: Int) {
+    if (inSub && index == 0) {
+      inSub = false
+      notifyDataSetChanged()
+      return
+    }
+
+    dialog.setActionButtonEnabled(POSITIVE, true)
+
+    if (inSub) {
+      val previousSelection = selectedSubIndex
+      selectedSubIndex = index
+      notifyItemChanged(previousSelection)
+      notifyItemChanged(selectedSubIndex)
+      invokeCallback()
+      return
+    }
+
+    if (index != selectedTopIndex) {
+      // Different than previous selected top, reset sub index
+      selectedSubIndex = -1
+    }
+
+    selectedTopIndex = index
+    if (subColors != null) {
+      inSub = true
+      // Preselect top color in sub-colors if it exists
+      selectedSubIndex = subColors[selectedTopIndex].indexOfFirst { it == colors[selectedTopIndex] }
+    }
+
+    invokeCallback()
+    notifyDataSetChanged()
+
+  }
+
+  fun selectedColor(): Int? {
+    if (selectedTopIndex > -1) {
+      if (selectedSubIndex > -1 && subColors != null) {
+        return subColors[selectedTopIndex][selectedSubIndex - 1]
+      }
+      return colors[selectedTopIndex]
+    }
+    return null
+  }
+
+  init {
+    if (initialSelection != null) {
+      selectedTopIndex = colors.indexOfFirst { it == initialSelection }
+      if (selectedTopIndex == -1 && subColors != null) {
+        for (section in subColors) {
+          selectedSubIndex = section.indexOfFirst { it == initialSelection }
+          if (selectedSubIndex != -1) {
+            inSub = true
+            break
+          }
+        }
+      }
+    }
+  }
+
+  override fun getItemViewType(position: Int): Int {
+    if (inSub && position == 0) {
+      return 1
+    }
+    return 0
+  }
+
+  override fun onCreateViewHolder(
+    parent: ViewGroup,
+    viewType: Int
+  ): ColorGridViewHolder {
+    val layoutRes =
+      if (viewType == 1) R.layout.md_color_grid_item_goup
+      else R.layout.md_color_grid_item
+    val view = LayoutInflater.from(parent.context)
+        .inflate(layoutRes, parent, false)
+    return ColorGridViewHolder(view, this)
+  }
+
+  override fun getItemCount() = if (inSub) subColors!![selectedTopIndex].size + 1 else colors.size
+
+  override fun onBindViewHolder(
+    holder: ColorGridViewHolder,
+    position: Int
+  ) {
+    if (inSub && position == 0) {
+      holder.iconView.setImageResource(upIcon)
+      return
+    }
+
+    val color =
+      if (inSub) subColors!![selectedTopIndex][position - 1]
+      else colors[position]
+
+    holder.colorCircle!!.color = color
+    holder.colorCircle.border =
+        getColor(holder.itemView.context, attr = attr.textColorPrimary)
+
+    holder.iconView.setImageResource(
+        if (color.isColorDark()) R.drawable.icon_checkmark_white
+        else R.drawable.icon_checkmark_black
+    )
+    holder.iconView.setVisibleOrGone(
+        if (inSub) position == selectedSubIndex
+        else position == selectedTopIndex
+    )
+  }
+
+  private fun invokeCallback() {
+    val actualWaitForPositive = waitForPositiveButton && dialog.hasActionButtons()
+    if (!actualWaitForPositive) {
+      callback?.invoke(dialog, selectedColor()!!)
+    }
+  }
+}

+ 75 - 0
color/src/main/java/com/afollestad/materialdialogs/color/DialogColorChooserExt.kt

@@ -0,0 +1,75 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+package com.afollestad.materialdialogs.color
+
+import android.annotation.SuppressLint
+import android.support.annotation.CheckResult
+import android.support.annotation.ColorInt
+import android.support.v7.widget.GridLayoutManager
+import android.support.v7.widget.RecyclerView
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.WhichButton.POSITIVE
+import com.afollestad.materialdialogs.actions.setActionButtonEnabled
+import com.afollestad.materialdialogs.customview.customView
+import com.afollestad.materialdialogs.customview.getCustomView
+
+typealias ColorCallback = ((dialog: MaterialDialog, color: Int) -> Unit)?
+
+/**
+ * Shows a dialog with a grid of colors that the user can select from.
+ *
+ * @param colors The top-level array of colors integers to display in the grid.
+ * @param subColors Optional sub-level colors which exist under each top-level color.
+ * @param initialSelection The optionally initially selected color literal integer.
+ * @param waitForPositiveButton When true, the selection isn't invoked until the user selects
+ *    a color and taps on the positive action button. Defaults to true if the dialog has buttons.
+ * @param selection An optional callback invoked when the user selects a color.
+ */
+@SuppressLint("CheckResult")
+@CheckResult
+fun MaterialDialog.colorChooser(
+  colors: IntArray,
+  subColors: Array<IntArray>? = null,
+  @ColorInt initialSelection: Int? = null,
+  waitForPositiveButton: Boolean = true,
+  selection: ColorCallback = null
+): MaterialDialog {
+  customView(R.layout.md_color_chooser_grid)
+  val customView = getCustomView() as RecyclerView
+
+  if (subColors != null && colors.size != subColors.size) {
+    throw IllegalStateException("Sub-colors array size should match the colors array size.")
+  }
+
+  val gridColumnCount = windowContext.resources
+      .getInteger(R.integer.color_grid_column_count)
+  customView.layoutManager = GridLayoutManager(
+      windowContext, gridColumnCount
+  )
+
+  val adapter = ColorGridAdapter(
+      dialog = this,
+      colors = colors,
+      subColors = subColors,
+      initialSelection = initialSelection,
+      waitForPositiveButton = waitForPositiveButton,
+      callback = selection
+  )
+  customView.adapter = adapter
+
+  if (waitForPositiveButton && selection != null) {
+    setActionButtonEnabled(POSITIVE, false)
+    positiveButton {
+      val color = adapter.selectedColor()
+      if (color != null) {
+        selection.invoke(this, color)
+      }
+    }
+  }
+
+  return this
+}

+ 37 - 0
color/src/main/java/com/afollestad/materialdialogs/color/utilext/ColorUtilExt.kt

@@ -0,0 +1,37 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+package com.afollestad.materialdialogs.color.utilext
+
+import android.content.Context
+import android.graphics.Color
+import android.support.annotation.AttrRes
+import android.support.annotation.ColorInt
+import android.support.annotation.ColorRes
+import android.support.v4.content.ContextCompat
+
+@ColorInt
+internal fun getColor(
+  context: Context,
+  @ColorRes res: Int? = null,
+  @AttrRes attr: Int? = null
+): Int {
+  if (attr != null) {
+    val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
+    try {
+      return a.getColor(0, Color.BLACK)
+    } finally {
+      a.recycle()
+    }
+  }
+  return ContextCompat.getColor(context, res ?: 0)
+}
+
+internal fun Int.isColorDark(): Boolean {
+  val darkness =
+    1 - (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255
+  return darkness >= 0.5
+}

+ 20 - 0
color/src/main/java/com/afollestad/materialdialogs/color/utilext/ViewUtilExt.kt

@@ -0,0 +1,20 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+package com.afollestad.materialdialogs.color.utilext
+
+import android.support.annotation.DimenRes
+import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
+
+internal fun <T : View> T.dimenPx(@DimenRes res: Int): Int {
+  return context.resources.getDimensionPixelSize(res)
+}
+
+internal fun <T : View> T.setVisibleOrGone(visible: Boolean) {
+  visibility = if (visible) VISIBLE else GONE
+}

+ 0 - 0
commons/src/main/res-public/values/public.xml → color/src/main/res-public/values/public.xml


+ 10 - 0
color/src/main/res/drawable/icon_back_black.xml

@@ -0,0 +1,10 @@
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="36dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:width="36dp">
+  <path
+      android:fillColor="#000000"
+      android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
+</vector>

+ 10 - 0
color/src/main/res/drawable/icon_back_white.xml

@@ -0,0 +1,10 @@
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="36dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:width="36dp">
+  <path
+      android:fillColor="#FFFFFF"
+      android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
+</vector>

+ 10 - 0
color/src/main/res/drawable/icon_checkmark_black.xml

@@ -0,0 +1,10 @@
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="32dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:width="32dp">
+  <path
+      android:fillColor="#000000"
+      android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
+</vector>

+ 10 - 0
color/src/main/res/drawable/icon_checkmark_white.xml

@@ -0,0 +1,10 @@
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="32dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
+    android:width="32dp">
+  <path
+      android:fillColor="#FFFFFF"
+      android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
+</vector>

+ 10 - 0
color/src/main/res/layout/md_color_chooser_grid.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.RecyclerView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:clipToPadding="false"
+    android:paddingBottom="@dimen/color_grid_padding_bottom"
+    android:paddingLeft="@dimen/color_grid_item_padding_double"
+    android:paddingRight="@dimen/color_grid_item_padding_double"
+    />

+ 29 - 0
color/src/main/res/layout/md_color_grid_item.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?selectableItemBackground"
+    android:padding="@dimen/color_grid_item_padding"
+    tools:layout_height="56dp"
+    tools:layout_width="56dp"
+    >
+
+  <com.afollestad.materialdialogs.color.ColorCircleView
+      android:id="@+id/color_view"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center"
+      />
+
+  <ImageView
+      android:id="@+id/icon"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center"
+      android:src="@drawable/icon_checkmark_white"
+      tools:ignore="ContentDescription"
+      />
+
+</FrameLayout>

+ 22 - 0
color/src/main/res/layout/md_color_grid_item_goup.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?selectableItemBackground"
+    android:padding="@dimen/color_grid_item_padding"
+    tools:layout_height="56dp"
+    tools:layout_width="56dp"
+    >
+
+  <ImageView
+      android:id="@+id/icon"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:layout_gravity="center"
+      android:src="@drawable/icon_back_black"
+      tools:ignore="ContentDescription"
+      />
+
+</FrameLayout>

+ 4 - 0
color/src/main/res/values-land/integers.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <integer name="color_grid_column_count">5</integer>
+</resources>

+ 4 - 0
color/src/main/res/values-large-land/integers.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <integer name="color_grid_column_count">7</integer>
+</resources>

+ 4 - 0
color/src/main/res/values-large/integers.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <integer name="color_grid_column_count">6</integer>
+</resources>

+ 7 - 0
color/src/main/res/values/dimens.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <dimen name="color_circle_view_border">1dp</dimen>
+  <dimen name="color_grid_item_padding">8dp</dimen>
+  <dimen name="color_grid_item_padding_double">16dp</dimen>
+  <dimen name="color_grid_padding_bottom">12dp</dimen>
+</resources>

+ 4 - 0
color/src/main/res/values/integers.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <integer name="color_grid_column_count">4</integer>
+</resources>

+ 0 - 47
commons/build.gradle

@@ -1,47 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-apply plugin: 'com.novoda.bintray-release'
-apply from: '../gradle/dependencies.gradle'
-
-android {
-    compileSdkVersion versions.compileSdk
-    buildToolsVersion versions.buildTools
-
-    defaultConfig {
-        minSdkVersion versions.minSdk
-        targetSdkVersion versions.compileSdk
-        versionCode versions.publishVersionCode
-        versionName versions.publishVersion
-    }
-    lintOptions {
-        abortOnError false
-        checkReleaseBuilds false
-    }
-    sourceSets {
-        main.res.srcDirs = [
-            'src/main/res',
-            'src/main/res-public'
-        ]
-    }
-}
-
-dependencies {
-    implementation 'com.google.code.findbugs:jsr305:' + versions.findBugs
-    implementation 'com.android.support:appcompat-v7:' + versions.supportLib
-    implementation 'com.android.support:support-annotations:' + versions.supportLib
-    implementation 'com.android.support:recyclerview-v7:' + versions.supportLib
-    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:' + versions.kotlin
-    implementation project(':core')
-}
-
-publish {
-    userOrg = 'novoda'
-    groupId = 'com.afollestad.material-dialogs'
-    artifactId = 'commons'
-    publishVersion = versions.publishVersion
-    website = 'https://github.com/afollestad/material-dialogs'
-    desc = 'A beautiful, fluid, and customizable dialogs API. '
-}
-repositories {
-    mavenCentral()
-}

+ 0 - 3
commons/src/main/AndroidManifest.xml

@@ -1,3 +0,0 @@
-<manifest package="com.afollestad.materialdialogs.commons">
-  <application />
-</manifest>

+ 0 - 208
commons/src/main/java/com/afollestad/materialdialogs/color/CircleView.java

@@ -1,208 +0,0 @@
-package com.afollestad.materialdialogs.color;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.RippleDrawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.StateListDrawable;
-import android.graphics.drawable.shapes.OvalShape;
-import android.os.Build;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.annotation.FloatRange;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.view.ViewCompat;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.widget.FrameLayout;
-import android.widget.Toast;
-import com.afollestad.materialdialogs.util.DialogUtils;
-
-public class CircleView extends FrameLayout {
-
-  private final int borderWidthSmall;
-  private final int borderWidthLarge;
-
-  private final Paint outerPaint;
-  private final Paint whitePaint;
-  private final Paint innerPaint;
-  private boolean selected;
-
-  public CircleView(Context context) {
-    this(context, null, 0);
-  }
-
-  public CircleView(Context context, AttributeSet attrs) {
-    this(context, attrs, 0);
-  }
-
-  public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    final Resources r = getResources();
-    borderWidthSmall =
-        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, r.getDisplayMetrics());
-    borderWidthLarge =
-        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, r.getDisplayMetrics());
-
-    whitePaint = new Paint();
-    whitePaint.setAntiAlias(true);
-    whitePaint.setColor(Color.WHITE);
-    innerPaint = new Paint();
-    innerPaint.setAntiAlias(true);
-    outerPaint = new Paint();
-    outerPaint.setAntiAlias(true);
-
-    update(Color.DKGRAY);
-    setWillNotDraw(false);
-  }
-
-  @ColorInt
-  private static int translucentColor(int color) {
-    final float factor = 0.7f;
-    int alpha = Math.round(Color.alpha(color) * factor);
-    int red = Color.red(color);
-    int green = Color.green(color);
-    int blue = Color.blue(color);
-    return Color.argb(alpha, red, green, blue);
-  }
-
-  @ColorInt
-  public static int shiftColor(@ColorInt int color, @FloatRange(from = 0.0f, to = 2.0f) float by) {
-    if (by == 1f) {
-      return color;
-    }
-    float[] hsv = new float[3];
-    Color.colorToHSV(color, hsv);
-    hsv[2] *= by; // value component
-    return Color.HSVToColor(hsv);
-  }
-
-  @ColorInt
-  public static int shiftColorDown(@ColorInt int color) {
-    return shiftColor(color, 0.9f);
-  }
-
-  @ColorInt
-  public static int shiftColorUp(@ColorInt int color) {
-    return shiftColor(color, 1.1f);
-  }
-
-  private void update(@ColorInt int color) {
-    innerPaint.setColor(color);
-    outerPaint.setColor(shiftColorDown(color));
-
-    Drawable selector = createSelector(color);
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      int[][] states = new int[][] {new int[] {android.R.attr.state_pressed}};
-      int[] colors = new int[] {shiftColorUp(color)};
-      ColorStateList rippleColors = new ColorStateList(states, colors);
-      setForeground(new RippleDrawable(rippleColors, selector, null));
-    } else {
-      setForeground(selector);
-    }
-  }
-
-  @Override
-  public void setBackgroundColor(@ColorInt int color) {
-    update(color);
-    requestLayout();
-    invalidate();
-  }
-
-  @Override
-  public void setBackgroundResource(@ColorRes int color) {
-    setBackgroundColor(DialogUtils.getColor(getContext(), color));
-  }
-
-  /** @deprecated */
-  @Deprecated
-  @Override
-  public void setBackground(Drawable background) {
-    throw new IllegalStateException("Cannot use setBackground() on CircleView.");
-  }
-
-  /** @deprecated */
-  @SuppressWarnings("deprecation")
-  @Deprecated
-  @Override
-  public void setBackgroundDrawable(Drawable background) {
-    throw new IllegalStateException("Cannot use setBackgroundDrawable() on CircleView.");
-  }
-
-  /** @deprecated */
-  @SuppressWarnings("deprecation")
-  @Deprecated
-  @Override
-  public void setActivated(boolean activated) {
-    throw new IllegalStateException("Cannot use setActivated() on CircleView.");
-  }
-
-  public void setSelected(boolean selected) {
-    this.selected = selected;
-    requestLayout();
-    invalidate();
-  }
-
-  @Override
-  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
-    setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
-  }
-
-  @Override
-  protected void onDraw(Canvas canvas) {
-    super.onDraw(canvas);
-    final int outerRadius = getMeasuredWidth() / 2;
-    if (selected) {
-      final int whiteRadius = outerRadius - borderWidthLarge;
-      final int innerRadius = whiteRadius - borderWidthSmall;
-      canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, outerRadius, outerPaint);
-      canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, whiteRadius, whitePaint);
-      canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, innerRadius, innerPaint);
-    } else {
-      canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, outerRadius, innerPaint);
-    }
-  }
-
-  private Drawable createSelector(int color) {
-    ShapeDrawable darkerCircle = new ShapeDrawable(new OvalShape());
-    darkerCircle.getPaint().setColor(translucentColor(shiftColorUp(color)));
-    StateListDrawable stateListDrawable = new StateListDrawable();
-    stateListDrawable.addState(new int[] {android.R.attr.state_pressed}, darkerCircle);
-    return stateListDrawable;
-  }
-
-  public void showHint(int color) {
-    final int[] screenPos = new int[2];
-    final Rect displayFrame = new Rect();
-    getLocationOnScreen(screenPos);
-    getWindowVisibleDisplayFrame(displayFrame);
-    final Context context = getContext();
-    final int width = getWidth();
-    final int height = getHeight();
-    final int midy = screenPos[1] + height / 2;
-    int referenceX = screenPos[0] + width / 2;
-    if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR) {
-      final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
-      referenceX = screenWidth - referenceX; // mirror
-    }
-    Toast cheatSheet =
-        Toast.makeText(context, String.format("#%06X", 0xFFFFFF & color), Toast.LENGTH_SHORT);
-    if (midy < displayFrame.height()) {
-      // Show along the top; follow action buttons
-      cheatSheet.setGravity(
-          Gravity.TOP | GravityCompat.END, referenceX, screenPos[1] + height - displayFrame.top);
-    } else {
-      // Show along the bottom center
-      cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
-    }
-    cheatSheet.show();
-  }
-}

+ 0 - 808
commons/src/main/java/com/afollestad/materialdialogs/color/ColorChooserDialog.java

@@ -1,808 +0,0 @@
-package com.afollestad.materialdialogs.color;
-
-import android.annotation.SuppressLint;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.graphics.Color;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.annotation.ArrayRes;
-import android.support.annotation.ColorInt;
-import android.support.annotation.Nullable;
-import android.support.annotation.StringRes;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.content.res.ResourcesCompat;
-import android.text.Editable;
-import android.text.InputFilter;
-import android.text.TextWatcher;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.GridView;
-import android.widget.SeekBar;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.afollestad.materialdialogs.Theme;
-import com.afollestad.materialdialogs.commons.R;
-import com.afollestad.materialdialogs.internal.MDTintHelper;
-import com.afollestad.materialdialogs.util.DialogUtils;
-import java.io.Serializable;
-import java.util.Locale;
-
-/** @author Aidan Follestad (afollestad) */
-@SuppressWarnings({"FieldCanBeLocal", "ConstantConditions", "unused"})
-public class ColorChooserDialog extends DialogFragment
-    implements View.OnClickListener, View.OnLongClickListener {
-
-  private int[] colorsTop;
-  @Nullable private int[][] colorsSub;
-  private int circleSize;
-  private ColorCallback callback;
-  private GridView grid;
-  private View colorChooserCustomFrame;
-  private EditText customColorHex;
-  private View customColorIndicator;
-  private TextWatcher customColorTextWatcher;
-  private SeekBar customSeekA;
-  private TextView customSeekAValue;
-  private SeekBar customSeekR;
-  private TextView customSeekRValue;
-  private SeekBar customSeekG;
-  private TextView customSeekGValue;
-  private SeekBar customSeekB;
-  private TextView customSeekBValue;
-  private SeekBar.OnSeekBarChangeListener customColorRgbListener;
-  private int selectedCustomColor;
-
-  public ColorChooserDialog() {}
-
-  @Nullable
-  public static ColorChooserDialog findVisible(FragmentManager fragmentManager, Tag tag) {
-    Fragment frag = fragmentManager.findFragmentByTag(tag.toString());
-    if (frag != null && frag instanceof ColorChooserDialog) {
-      return (ColorChooserDialog) frag;
-    }
-    return null;
-  }
-
-  private void generateColors() {
-    Builder builder = getBuilder();
-    if (builder.colorsTop != null) {
-      colorsTop = builder.colorsTop;
-      colorsSub = builder.colorsSub;
-      return;
-    }
-
-    if (builder.accentMode) {
-      colorsTop = ColorPalette.ACCENT_COLORS;
-      colorsSub = ColorPalette.ACCENT_COLORS_SUB;
-    } else {
-      colorsTop = ColorPalette.PRIMARY_COLORS;
-      colorsSub = ColorPalette.PRIMARY_COLORS_SUB;
-    }
-  }
-
-  @Override
-  public void onSaveInstanceState(Bundle outState) {
-    super.onSaveInstanceState(outState);
-    outState.putInt("top_index", topIndex());
-    outState.putBoolean("in_sub", isInSub());
-    outState.putInt("sub_index", subIndex());
-    outState.putBoolean(
-        "in_custom",
-        colorChooserCustomFrame != null && colorChooserCustomFrame.getVisibility() == View.VISIBLE);
-  }
-
-  @Override
-  public void onAttach(Context context) {
-    super.onAttach(context);
-    if (getActivity() instanceof ColorCallback) {
-      callback = (ColorCallback) getActivity();
-    } else if (getTargetFragment() instanceof ColorCallback) {
-      callback = (ColorCallback) getTargetFragment();
-    } else {
-      throw new IllegalStateException(
-          "ColorChooserDialog needs to be shown from an Activity/Fragment implementing ColorCallback.");
-    }
-  }
-
-  private boolean isInSub() {
-    return getArguments().getBoolean("in_sub", false);
-  }
-
-  private void isInSub(boolean value) {
-    getArguments().putBoolean("in_sub", value);
-  }
-
-  private int topIndex() {
-    return getArguments().getInt("top_index", -1);
-  }
-
-  private void topIndex(int value) {
-    if (value > -1) {
-      findSubIndexForColor(value, colorsTop[value]);
-    }
-    getArguments().putInt("top_index", value);
-  }
-
-  private int subIndex() {
-    if (colorsSub == null) {
-      return -1;
-    }
-    return getArguments().getInt("sub_index", -1);
-  }
-
-  private void subIndex(int value) {
-    if (colorsSub == null) {
-      return;
-    }
-    getArguments().putInt("sub_index", value);
-  }
-
-  @StringRes
-  public int getTitle() {
-    Builder builder = getBuilder();
-    int title;
-    if (isInSub()) {
-      title = builder.titleSub;
-    } else {
-      title = builder.title;
-    }
-    if (title == 0) {
-      title = builder.title;
-    }
-    return title;
-  }
-
-  public String tag() {
-    Builder builder = getBuilder();
-    if (builder.tag != null) {
-      return builder.tag;
-    } else {
-      return super.getTag();
-    }
-  }
-
-  public boolean isAccentMode() {
-    return getBuilder().accentMode;
-  }
-
-  @Override
-  public void onClick(View v) {
-    if (v.getTag() != null) {
-      final String[] tag = ((String) v.getTag()).split(":");
-      final int index = Integer.parseInt(tag[0]);
-      final MaterialDialog dialog = (MaterialDialog) getDialog();
-      final Builder builder = getBuilder();
-
-      if (isInSub()) {
-        subIndex(index);
-      } else {
-        topIndex(index);
-        if (colorsSub != null && index < colorsSub.length) {
-          dialog.setActionButton(DialogAction.NEGATIVE, builder.backBtn);
-          isInSub(true);
-        }
-      }
-
-      if (builder.allowUserCustom) {
-        selectedCustomColor = getSelectedColor();
-      }
-      invalidateDynamicButtonColors();
-      invalidate();
-    }
-  }
-
-  @Override
-  public boolean onLongClick(View v) {
-    if (v.getTag() != null) {
-      final String[] tag = ((String) v.getTag()).split(":");
-      final int color = Integer.parseInt(tag[1]);
-      ((CircleView) v).showHint(color);
-      return true;
-    }
-    return false;
-  }
-
-  private void invalidateDynamicButtonColors() {
-    final MaterialDialog dialog = (MaterialDialog) getDialog();
-    if (dialog == null) {
-      return;
-    }
-    final Builder builder = getBuilder();
-    if (builder.dynamicButtonColor) {
-      int selectedColor = getSelectedColor();
-      if (Color.alpha(selectedColor) < 64
-          || (Color.red(selectedColor) > 247
-              && Color.green(selectedColor) > 247
-              && Color.blue(selectedColor) > 247)) {
-        // Once we get close to white or transparent,
-        // the action buttons and seekbars will be a very light gray.
-        selectedColor = Color.parseColor("#DEDEDE");
-      }
-
-      if (getBuilder().dynamicButtonColor) {
-        dialog.getActionButton(DialogAction.POSITIVE).setTextColor(selectedColor);
-        dialog.getActionButton(DialogAction.NEGATIVE).setTextColor(selectedColor);
-        dialog.getActionButton(DialogAction.NEUTRAL).setTextColor(selectedColor);
-      }
-
-      if (customSeekR != null) {
-        if (customSeekA.getVisibility() == View.VISIBLE) {
-          MDTintHelper.setTint(customSeekA, selectedColor);
-        }
-        MDTintHelper.setTint(customSeekR, selectedColor);
-        MDTintHelper.setTint(customSeekG, selectedColor);
-        MDTintHelper.setTint(customSeekB, selectedColor);
-      }
-    }
-  }
-
-  @ColorInt
-  private int getSelectedColor() {
-    if (colorChooserCustomFrame != null
-        && colorChooserCustomFrame.getVisibility() == View.VISIBLE) {
-      return selectedCustomColor;
-    }
-
-    int color = 0;
-    if (subIndex() > -1) {
-      color = colorsSub[topIndex()][subIndex()];
-    } else if (topIndex() > -1) {
-      color = colorsTop[topIndex()];
-    }
-    if (color == 0) {
-      int fallback = 0;
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-        fallback = DialogUtils.resolveColor(getActivity(), android.R.attr.colorAccent);
-      }
-      color = DialogUtils.resolveColor(getActivity(), R.attr.colorAccent, fallback);
-    }
-    return color;
-  }
-
-  private void findSubIndexForColor(int topIndex, int color) {
-    if (colorsSub == null || colorsSub.length - 1 < topIndex) {
-      return;
-    }
-    int[] subColors = colorsSub[topIndex];
-    for (int subIndex = 0; subIndex < subColors.length; subIndex++) {
-      if (subColors[subIndex] == color) {
-        subIndex(subIndex);
-        break;
-      }
-    }
-  }
-
-  @Override
-  public Dialog onCreateDialog(Bundle savedInstanceState) {
-    if (getArguments() == null || !getArguments().containsKey("builder")) {
-      throw new IllegalStateException(
-          "ColorChooserDialog should be created using its Builder interface.");
-    }
-    generateColors();
-
-    int preselectColor;
-    boolean foundPreselectColor = false;
-
-    if (savedInstanceState != null) {
-      foundPreselectColor = !savedInstanceState.getBoolean("in_custom", false);
-      preselectColor = getSelectedColor();
-    } else {
-      if (getBuilder().setPreselectionColor) {
-        preselectColor = getBuilder().preselectColor;
-        if (preselectColor != 0) {
-          for (int topIndex = 0; topIndex < colorsTop.length; topIndex++) {
-            if (colorsTop[topIndex] == preselectColor) {
-              foundPreselectColor = true;
-              topIndex(topIndex);
-              if (getBuilder().accentMode) {
-                subIndex(2);
-              } else if (colorsSub != null) {
-                findSubIndexForColor(topIndex, preselectColor);
-              } else {
-                subIndex(5);
-              }
-              break;
-            }
-
-            if (colorsSub != null) {
-              for (int subIndex = 0; subIndex < colorsSub[topIndex].length; subIndex++) {
-                if (colorsSub[topIndex][subIndex] == preselectColor) {
-                  foundPreselectColor = true;
-                  topIndex(topIndex);
-                  subIndex(subIndex);
-                  break;
-                }
-              }
-              if (foundPreselectColor) {
-                break;
-              }
-            }
-          }
-        }
-      } else {
-        preselectColor = Color.BLACK;
-        foundPreselectColor = true;
-      }
-    }
-
-    circleSize = getResources().getDimensionPixelSize(R.dimen.md_colorchooser_circlesize);
-    final Builder builder = getBuilder();
-
-    MaterialDialog.Builder bd =
-        new MaterialDialog.Builder(getActivity())
-            .title(getTitle())
-            .autoDismiss(false)
-            .customView(R.layout.md_dialog_colorchooser, false)
-            .negativeText(builder.cancelBtn)
-            .positiveText(builder.doneBtn)
-            .neutralText(builder.allowUserCustom ? builder.customBtn : 0)
-            .typeface(builder.mediumFont, builder.regularFont)
-            .onPositive(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    callback.onColorSelection(ColorChooserDialog.this, getSelectedColor());
-                    dismiss();
-                  }
-                })
-            .onNegative(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    if (isInSub()) {
-                      dialog.setActionButton(DialogAction.NEGATIVE, getBuilder().cancelBtn);
-                      isInSub(false);
-                      subIndex(-1); // Do this to avoid ArrayIndexOutOfBoundsException
-                      invalidate();
-                    } else {
-                      dialog.cancel();
-                    }
-                  }
-                })
-            .onNeutral(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    toggleCustom(dialog);
-                  }
-                })
-            .showListener(
-                new DialogInterface.OnShowListener() {
-                  @Override
-                  public void onShow(DialogInterface dialog) {
-                    invalidateDynamicButtonColors();
-                  }
-                });
-
-    if (builder.theme != null) {
-      bd.theme(builder.theme);
-    }
-
-    final MaterialDialog dialog = bd.build();
-    final View v = dialog.getCustomView();
-    grid = v.findViewById(R.id.md_grid);
-
-    if (builder.allowUserCustom) {
-      selectedCustomColor = preselectColor;
-      colorChooserCustomFrame = v.findViewById(R.id.md_colorChooserCustomFrame);
-      customColorHex = v.findViewById(R.id.md_hexInput);
-      customColorIndicator = v.findViewById(R.id.md_colorIndicator);
-      customSeekA = v.findViewById(R.id.md_colorA);
-      customSeekAValue = v.findViewById(R.id.md_colorAValue);
-      customSeekR = v.findViewById(R.id.md_colorR);
-      customSeekRValue = v.findViewById(R.id.md_colorRValue);
-      customSeekG = v.findViewById(R.id.md_colorG);
-      customSeekGValue = v.findViewById(R.id.md_colorGValue);
-      customSeekB = v.findViewById(R.id.md_colorB);
-      customSeekBValue = v.findViewById(R.id.md_colorBValue);
-
-      if (!builder.allowUserCustomAlpha) {
-        v.findViewById(R.id.md_colorALabel).setVisibility(View.GONE);
-        customSeekA.setVisibility(View.GONE);
-        customSeekAValue.setVisibility(View.GONE);
-        customColorHex.setHint("2196F3");
-        customColorHex.setFilters(new InputFilter[] {new InputFilter.LengthFilter(6)});
-      } else {
-        customColorHex.setHint("FF2196F3");
-        customColorHex.setFilters(new InputFilter[] {new InputFilter.LengthFilter(8)});
-      }
-
-      if (!foundPreselectColor) {
-        // If color wasn't found in the preset colors, it must be custom
-        toggleCustom(dialog);
-      }
-    }
-
-    invalidate();
-    return dialog;
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    if (callback != null) {
-      callback.onColorChooserDismissed(this);
-    }
-  }
-
-  private void toggleCustom(MaterialDialog dialog) {
-    if (dialog == null) {
-      dialog = (MaterialDialog) getDialog();
-    }
-    if (grid.getVisibility() == View.VISIBLE) {
-      dialog.setTitle(getBuilder().customBtn);
-      dialog.setActionButton(DialogAction.NEUTRAL, getBuilder().presetsBtn);
-      dialog.setActionButton(DialogAction.NEGATIVE, getBuilder().cancelBtn);
-      grid.setVisibility(View.INVISIBLE);
-      colorChooserCustomFrame.setVisibility(View.VISIBLE);
-
-      customColorTextWatcher =
-          new TextWatcher() {
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-              try {
-                selectedCustomColor = Color.parseColor("#" + s.toString());
-              } catch (IllegalArgumentException e) {
-                selectedCustomColor = Color.BLACK;
-              }
-              customColorIndicator.setBackgroundColor(selectedCustomColor);
-              if (customSeekA.getVisibility() == View.VISIBLE) {
-                int alpha = Color.alpha(selectedCustomColor);
-                customSeekA.setProgress(alpha);
-                customSeekAValue.setText(String.format(Locale.US, "%d", alpha));
-              }
-              int red = Color.red(selectedCustomColor);
-              customSeekR.setProgress(red);
-              int green = Color.green(selectedCustomColor);
-              customSeekG.setProgress(green);
-              int blue = Color.blue(selectedCustomColor);
-              customSeekB.setProgress(blue);
-              isInSub(false);
-              topIndex(-1);
-              subIndex(-1);
-              invalidateDynamicButtonColors();
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {}
-          };
-
-      customColorHex.addTextChangedListener(customColorTextWatcher);
-      customColorRgbListener =
-          new SeekBar.OnSeekBarChangeListener() {
-            @SuppressLint("DefaultLocale")
-            @Override
-            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-              if (fromUser) {
-                if (getBuilder().allowUserCustomAlpha) {
-                  int color =
-                      Color.argb(
-                          customSeekA.getProgress(),
-                          customSeekR.getProgress(),
-                          customSeekG.getProgress(),
-                          customSeekB.getProgress());
-                  customColorHex.setText(String.format("%08X", color));
-                } else {
-                  int color =
-                      Color.rgb(
-                          customSeekR.getProgress(),
-                          customSeekG.getProgress(),
-                          customSeekB.getProgress());
-                  customColorHex.setText(String.format("%06X", 0xFFFFFF & color));
-                }
-              }
-              customSeekAValue.setText(String.format("%d", customSeekA.getProgress()));
-              customSeekRValue.setText(String.format("%d", customSeekR.getProgress()));
-              customSeekGValue.setText(String.format("%d", customSeekG.getProgress()));
-              customSeekBValue.setText(String.format("%d", customSeekB.getProgress()));
-            }
-
-            @Override
-            public void onStartTrackingTouch(SeekBar seekBar) {}
-
-            @Override
-            public void onStopTrackingTouch(SeekBar seekBar) {}
-          };
-
-      customSeekR.setOnSeekBarChangeListener(customColorRgbListener);
-      customSeekG.setOnSeekBarChangeListener(customColorRgbListener);
-      customSeekB.setOnSeekBarChangeListener(customColorRgbListener);
-      if (customSeekA.getVisibility() == View.VISIBLE) {
-        customSeekA.setOnSeekBarChangeListener(customColorRgbListener);
-        customColorHex.setText(String.format("%08X", selectedCustomColor));
-      } else {
-        customColorHex.setText(String.format("%06X", 0xFFFFFF & selectedCustomColor));
-      }
-    } else {
-      dialog.setTitle(getBuilder().title);
-      dialog.setActionButton(DialogAction.NEUTRAL, getBuilder().customBtn);
-      if (isInSub()) {
-        dialog.setActionButton(DialogAction.NEGATIVE, getBuilder().backBtn);
-      } else {
-        dialog.setActionButton(DialogAction.NEGATIVE, getBuilder().cancelBtn);
-      }
-      grid.setVisibility(View.VISIBLE);
-      colorChooserCustomFrame.setVisibility(View.GONE);
-      customColorHex.removeTextChangedListener(customColorTextWatcher);
-      customColorTextWatcher = null;
-      customSeekR.setOnSeekBarChangeListener(null);
-      customSeekG.setOnSeekBarChangeListener(null);
-      customSeekB.setOnSeekBarChangeListener(null);
-      customColorRgbListener = null;
-    }
-  }
-
-  private void invalidate() {
-    if (grid.getAdapter() == null) {
-      grid.setAdapter(new ColorGridAdapter());
-      grid.setSelector(
-          ResourcesCompat.getDrawable(getResources(), R.drawable.md_transparent, null));
-    } else {
-      ((BaseAdapter) grid.getAdapter()).notifyDataSetChanged();
-    }
-    if (getDialog() != null) {
-      getDialog().setTitle(getTitle());
-    }
-  }
-
-  private Builder getBuilder() {
-    if (getArguments() == null || !getArguments().containsKey("builder")) {
-      return null;
-    }
-    return (Builder) getArguments().getSerializable("builder");
-  }
-
-  private void dismissIfNecessary(FragmentManager fragmentManager, String tag) {
-    Fragment frag = fragmentManager.findFragmentByTag(tag);
-    if (frag != null) {
-      ((DialogFragment) frag).dismiss();
-      fragmentManager.beginTransaction().remove(frag).commit();
-    }
-  }
-
-  public ColorChooserDialog show() {
-    Tag tag;
-    Builder builder = getBuilder();
-    if (builder.colorsTop != null) {
-      tag = Tag.CUSTOM;
-    } else if (builder.accentMode) {
-      tag = Tag.ACCENT;
-    } else {
-      tag = Tag.PRIMARY;
-    }
-
-    final FragmentManager fragmentManager =
-        builder.fragment != null
-            ? builder.fragment.getChildFragmentManager()
-            : builder.activity.getSupportFragmentManager();
-    if (builder.fragment != null) {
-      setTargetFragment(builder.fragment, 67);
-    }
-
-    dismissIfNecessary(fragmentManager, tag.toString());
-    show(fragmentManager, tag.toString());
-    return this;
-  }
-
-  public enum Tag {
-    PRIMARY("COLOR_CHOOSER_PRIMARY"),
-    ACCENT("COLOR_CHOOSER_ACCENT"),
-    CUSTOM("COLOR_CHOOSER_CUSTOM");
-
-    private String value;
-
-    Tag(String value) {
-      this.value = value;
-    }
-
-    @Override
-    public String toString() {
-      return value;
-    }
-  }
-
-  public interface ColorCallback {
-
-    void onColorSelection(ColorChooserDialog dialog, @ColorInt int selectedColor);
-
-    void onColorChooserDismissed(ColorChooserDialog dialog);
-  }
-
-  @SuppressWarnings("SameParameterValue")
-  public static class Builder implements Serializable {
-
-    @Nullable final transient FragmentActivity activity;
-    @Nullable final transient Fragment fragment;
-
-    @Nullable String mediumFont;
-    @Nullable String regularFont;
-    @StringRes final int title;
-    @StringRes int titleSub;
-    @ColorInt int preselectColor;
-    @StringRes int doneBtn = R.string.md_done_label;
-    @StringRes int backBtn = R.string.md_back_label;
-    @StringRes int cancelBtn = R.string.md_cancel_label;
-    @StringRes int customBtn = R.string.md_custom_label;
-    @StringRes int presetsBtn = R.string.md_presets_label;
-    @Nullable int[] colorsTop;
-    @Nullable int[][] colorsSub;
-    @Nullable String tag;
-    @Nullable Theme theme;
-
-    boolean accentMode = false;
-    boolean dynamicButtonColor = true;
-    boolean allowUserCustom = true;
-    boolean allowUserCustomAlpha = true;
-    boolean setPreselectionColor = false;
-
-    public <T extends FragmentActivity & ColorCallback> Builder(T activity, @StringRes int title) {
-      this.activity = activity;
-      this.fragment = null;
-      this.title = title;
-    }
-
-    public <T extends Fragment & ColorCallback> Builder(T fragment, @StringRes int title) {
-      this.activity = null;
-      this.fragment = fragment;
-      this.title = title;
-    }
-
-    public Builder typeface(@Nullable String medium, @Nullable String regular) {
-      this.mediumFont = medium;
-      this.regularFont = regular;
-      return this;
-    }
-
-    public Builder titleSub(@StringRes int titleSub) {
-      this.titleSub = titleSub;
-      return this;
-    }
-
-    public Builder tag(@Nullable String tag) {
-      this.tag = tag;
-      return this;
-    }
-
-    public Builder theme(Theme theme) {
-      this.theme = theme;
-      return this;
-    }
-
-    public Builder preselect(@ColorInt int preselect) {
-      preselectColor = preselect;
-      setPreselectionColor = true;
-      return this;
-    }
-
-    public Builder accentMode(boolean accentMode) {
-      this.accentMode = accentMode;
-      return this;
-    }
-
-    public Builder doneButton(@StringRes int text) {
-      doneBtn = text;
-      return this;
-    }
-
-    public Builder backButton(@StringRes int text) {
-      backBtn = text;
-      return this;
-    }
-
-    public Builder cancelButton(@StringRes int text) {
-      cancelBtn = text;
-      return this;
-    }
-
-    public Builder customButton(@StringRes int text) {
-      customBtn = text;
-      return this;
-    }
-
-    public Builder presetsButton(@StringRes int text) {
-      presetsBtn = text;
-      return this;
-    }
-
-    public Builder dynamicButtonColor(boolean enabled) {
-      dynamicButtonColor = enabled;
-      return this;
-    }
-
-    public Builder customColors(int[] topLevel, @Nullable int[][] subLevel) {
-      colorsTop = topLevel;
-      colorsSub = subLevel;
-      return this;
-    }
-
-    public Builder customColors(@ArrayRes int topLevel, @Nullable int[][] subLevel) {
-      final Context context = fragment != null ? fragment.getContext() : activity;
-      colorsTop = DialogUtils.getColorArray(context, topLevel);
-      colorsSub = subLevel;
-      return this;
-    }
-
-    public Builder allowUserColorInput(boolean allow) {
-      allowUserCustom = allow;
-      return this;
-    }
-
-    public Builder allowUserColorInputAlpha(boolean allow) {
-      allowUserCustomAlpha = allow;
-      return this;
-    }
-
-    public ColorChooserDialog build() {
-      ColorChooserDialog dialog = new ColorChooserDialog();
-      Bundle args = new Bundle();
-      args.putSerializable("builder", this);
-      dialog.setArguments(args);
-      return dialog;
-    }
-
-    public ColorChooserDialog show() {
-      ColorChooserDialog dialog = build();
-      dialog.show();
-      return dialog;
-    }
-  }
-
-  private class ColorGridAdapter extends BaseAdapter {
-    ColorGridAdapter() {}
-
-    @Override
-    public int getCount() {
-      if (isInSub()) {
-        return colorsSub[topIndex()].length;
-      } else {
-        return colorsTop.length;
-      }
-    }
-
-    @Override
-    public Object getItem(int position) {
-      if (isInSub()) {
-        return colorsSub[topIndex()][position];
-      } else {
-        return colorsTop[position];
-      }
-    }
-
-    @Override
-    public long getItemId(int position) {
-      return position;
-    }
-
-    @SuppressLint("DefaultLocale")
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-      if (convertView == null) {
-        convertView = new CircleView(getContext());
-        convertView.setLayoutParams(new GridView.LayoutParams(circleSize, circleSize));
-      }
-      CircleView child = (CircleView) convertView;
-      @ColorInt final int color = isInSub() ? colorsSub[topIndex()][position] : colorsTop[position];
-      child.setBackgroundColor(color);
-      if (isInSub()) {
-        child.setSelected(subIndex() == position);
-      } else {
-        child.setSelected(topIndex() == position);
-      }
-      child.setTag(String.format("%d:%d", position, color));
-      child.setOnClickListener(ColorChooserDialog.this);
-      child.setOnLongClickListener(ColorChooserDialog.this);
-      return convertView;
-    }
-  }
-}

+ 0 - 382
commons/src/main/java/com/afollestad/materialdialogs/color/ColorPalette.java

@@ -1,382 +0,0 @@
-package com.afollestad.materialdialogs.color;
-
-import android.graphics.Color;
-
-/** @author Aidan Follestad (afollestad) */
-class ColorPalette {
-
-  static final int[] PRIMARY_COLORS =
-      new int[] {
-        Color.parseColor("#F44336"),
-        Color.parseColor("#E91E63"),
-        Color.parseColor("#9C27B0"),
-        Color.parseColor("#673AB7"),
-        Color.parseColor("#3F51B5"),
-        Color.parseColor("#2196F3"),
-        Color.parseColor("#03A9F4"),
-        Color.parseColor("#00BCD4"),
-        Color.parseColor("#009688"),
-        Color.parseColor("#4CAF50"),
-        Color.parseColor("#8BC34A"),
-        Color.parseColor("#CDDC39"),
-        Color.parseColor("#FFEB3B"),
-        Color.parseColor("#FFC107"),
-        Color.parseColor("#FF9800"),
-        Color.parseColor("#FF5722"),
-        Color.parseColor("#795548"),
-        Color.parseColor("#9E9E9E"),
-        Color.parseColor("#607D8B")
-      };
-
-  static final int[][] PRIMARY_COLORS_SUB =
-      new int[][] {
-        new int[] {
-          Color.parseColor("#FFEBEE"),
-          Color.parseColor("#FFCDD2"),
-          Color.parseColor("#EF9A9A"),
-          Color.parseColor("#E57373"),
-          Color.parseColor("#EF5350"),
-          Color.parseColor("#F44336"),
-          Color.parseColor("#E53935"),
-          Color.parseColor("#D32F2F"),
-          Color.parseColor("#C62828"),
-          Color.parseColor("#B71C1C")
-        },
-        new int[] {
-          Color.parseColor("#FCE4EC"),
-          Color.parseColor("#F8BBD0"),
-          Color.parseColor("#F48FB1"),
-          Color.parseColor("#F06292"),
-          Color.parseColor("#EC407A"),
-          Color.parseColor("#E91E63"),
-          Color.parseColor("#D81B60"),
-          Color.parseColor("#C2185B"),
-          Color.parseColor("#AD1457"),
-          Color.parseColor("#880E4F")
-        },
-        new int[] {
-          Color.parseColor("#F3E5F5"),
-          Color.parseColor("#E1BEE7"),
-          Color.parseColor("#CE93D8"),
-          Color.parseColor("#BA68C8"),
-          Color.parseColor("#AB47BC"),
-          Color.parseColor("#9C27B0"),
-          Color.parseColor("#8E24AA"),
-          Color.parseColor("#7B1FA2"),
-          Color.parseColor("#6A1B9A"),
-          Color.parseColor("#4A148C")
-        },
-        new int[] {
-          Color.parseColor("#EDE7F6"),
-          Color.parseColor("#D1C4E9"),
-          Color.parseColor("#B39DDB"),
-          Color.parseColor("#9575CD"),
-          Color.parseColor("#7E57C2"),
-          Color.parseColor("#673AB7"),
-          Color.parseColor("#5E35B1"),
-          Color.parseColor("#512DA8"),
-          Color.parseColor("#4527A0"),
-          Color.parseColor("#311B92")
-        },
-        new int[] {
-          Color.parseColor("#E8EAF6"),
-          Color.parseColor("#C5CAE9"),
-          Color.parseColor("#9FA8DA"),
-          Color.parseColor("#7986CB"),
-          Color.parseColor("#5C6BC0"),
-          Color.parseColor("#3F51B5"),
-          Color.parseColor("#3949AB"),
-          Color.parseColor("#303F9F"),
-          Color.parseColor("#283593"),
-          Color.parseColor("#1A237E")
-        },
-        new int[] {
-          Color.parseColor("#E3F2FD"),
-          Color.parseColor("#BBDEFB"),
-          Color.parseColor("#90CAF9"),
-          Color.parseColor("#64B5F6"),
-          Color.parseColor("#42A5F5"),
-          Color.parseColor("#2196F3"),
-          Color.parseColor("#1E88E5"),
-          Color.parseColor("#1976D2"),
-          Color.parseColor("#1565C0"),
-          Color.parseColor("#0D47A1")
-        },
-        new int[] {
-          Color.parseColor("#E1F5FE"),
-          Color.parseColor("#B3E5FC"),
-          Color.parseColor("#81D4FA"),
-          Color.parseColor("#4FC3F7"),
-          Color.parseColor("#29B6F6"),
-          Color.parseColor("#03A9F4"),
-          Color.parseColor("#039BE5"),
-          Color.parseColor("#0288D1"),
-          Color.parseColor("#0277BD"),
-          Color.parseColor("#01579B")
-        },
-        new int[] {
-          Color.parseColor("#E0F7FA"),
-          Color.parseColor("#B2EBF2"),
-          Color.parseColor("#80DEEA"),
-          Color.parseColor("#4DD0E1"),
-          Color.parseColor("#26C6DA"),
-          Color.parseColor("#00BCD4"),
-          Color.parseColor("#00ACC1"),
-          Color.parseColor("#0097A7"),
-          Color.parseColor("#00838F"),
-          Color.parseColor("#006064")
-        },
-        new int[] {
-          Color.parseColor("#E0F2F1"),
-          Color.parseColor("#B2DFDB"),
-          Color.parseColor("#80CBC4"),
-          Color.parseColor("#4DB6AC"),
-          Color.parseColor("#26A69A"),
-          Color.parseColor("#009688"),
-          Color.parseColor("#00897B"),
-          Color.parseColor("#00796B"),
-          Color.parseColor("#00695C"),
-          Color.parseColor("#004D40")
-        },
-        new int[] {
-          Color.parseColor("#E8F5E9"),
-          Color.parseColor("#C8E6C9"),
-          Color.parseColor("#A5D6A7"),
-          Color.parseColor("#81C784"),
-          Color.parseColor("#66BB6A"),
-          Color.parseColor("#4CAF50"),
-          Color.parseColor("#43A047"),
-          Color.parseColor("#388E3C"),
-          Color.parseColor("#2E7D32"),
-          Color.parseColor("#1B5E20")
-        },
-        new int[] {
-          Color.parseColor("#F1F8E9"),
-          Color.parseColor("#DCEDC8"),
-          Color.parseColor("#C5E1A5"),
-          Color.parseColor("#AED581"),
-          Color.parseColor("#9CCC65"),
-          Color.parseColor("#8BC34A"),
-          Color.parseColor("#7CB342"),
-          Color.parseColor("#689F38"),
-          Color.parseColor("#558B2F"),
-          Color.parseColor("#33691E")
-        },
-        new int[] {
-          Color.parseColor("#F9FBE7"),
-          Color.parseColor("#F0F4C3"),
-          Color.parseColor("#E6EE9C"),
-          Color.parseColor("#DCE775"),
-          Color.parseColor("#D4E157"),
-          Color.parseColor("#CDDC39"),
-          Color.parseColor("#C0CA33"),
-          Color.parseColor("#AFB42B"),
-          Color.parseColor("#9E9D24"),
-          Color.parseColor("#827717")
-        },
-        new int[] {
-          Color.parseColor("#FFFDE7"),
-          Color.parseColor("#FFF9C4"),
-          Color.parseColor("#FFF59D"),
-          Color.parseColor("#FFF176"),
-          Color.parseColor("#FFEE58"),
-          Color.parseColor("#FFEB3B"),
-          Color.parseColor("#FDD835"),
-          Color.parseColor("#FBC02D"),
-          Color.parseColor("#F9A825"),
-          Color.parseColor("#F57F17")
-        },
-        new int[] {
-          Color.parseColor("#FFF8E1"),
-          Color.parseColor("#FFECB3"),
-          Color.parseColor("#FFE082"),
-          Color.parseColor("#FFD54F"),
-          Color.parseColor("#FFCA28"),
-          Color.parseColor("#FFC107"),
-          Color.parseColor("#FFB300"),
-          Color.parseColor("#FFA000"),
-          Color.parseColor("#FF8F00"),
-          Color.parseColor("#FF6F00")
-        },
-        new int[] {
-          Color.parseColor("#FFF3E0"),
-          Color.parseColor("#FFE0B2"),
-          Color.parseColor("#FFCC80"),
-          Color.parseColor("#FFB74D"),
-          Color.parseColor("#FFA726"),
-          Color.parseColor("#FF9800"),
-          Color.parseColor("#FB8C00"),
-          Color.parseColor("#F57C00"),
-          Color.parseColor("#EF6C00"),
-          Color.parseColor("#E65100")
-        },
-        new int[] {
-          Color.parseColor("#FBE9E7"),
-          Color.parseColor("#FFCCBC"),
-          Color.parseColor("#FFAB91"),
-          Color.parseColor("#FF8A65"),
-          Color.parseColor("#FF7043"),
-          Color.parseColor("#FF5722"),
-          Color.parseColor("#F4511E"),
-          Color.parseColor("#E64A19"),
-          Color.parseColor("#D84315"),
-          Color.parseColor("#BF360C")
-        },
-        new int[] {
-          Color.parseColor("#EFEBE9"),
-          Color.parseColor("#D7CCC8"),
-          Color.parseColor("#BCAAA4"),
-          Color.parseColor("#A1887F"),
-          Color.parseColor("#8D6E63"),
-          Color.parseColor("#795548"),
-          Color.parseColor("#6D4C41"),
-          Color.parseColor("#5D4037"),
-          Color.parseColor("#4E342E"),
-          Color.parseColor("#3E2723")
-        },
-        new int[] {
-          Color.parseColor("#FAFAFA"),
-          Color.parseColor("#F5F5F5"),
-          Color.parseColor("#EEEEEE"),
-          Color.parseColor("#E0E0E0"),
-          Color.parseColor("#BDBDBD"),
-          Color.parseColor("#9E9E9E"),
-          Color.parseColor("#757575"),
-          Color.parseColor("#616161"),
-          Color.parseColor("#424242"),
-          Color.parseColor("#212121")
-        },
-        new int[] {
-          Color.parseColor("#ECEFF1"),
-          Color.parseColor("#CFD8DC"),
-          Color.parseColor("#B0BEC5"),
-          Color.parseColor("#90A4AE"),
-          Color.parseColor("#78909C"),
-          Color.parseColor("#607D8B"),
-          Color.parseColor("#546E7A"),
-          Color.parseColor("#455A64"),
-          Color.parseColor("#37474F"),
-          Color.parseColor("#263238")
-        }
-      };
-
-  static final int[] ACCENT_COLORS =
-      new int[] {
-        Color.parseColor("#FF1744"),
-        Color.parseColor("#F50057"),
-        Color.parseColor("#D500F9"),
-        Color.parseColor("#651FFF"),
-        Color.parseColor("#3D5AFE"),
-        Color.parseColor("#2979FF"),
-        Color.parseColor("#00B0FF"),
-        Color.parseColor("#00E5FF"),
-        Color.parseColor("#1DE9B6"),
-        Color.parseColor("#00E676"),
-        Color.parseColor("#76FF03"),
-        Color.parseColor("#C6FF00"),
-        Color.parseColor("#FFEA00"),
-        Color.parseColor("#FFC400"),
-        Color.parseColor("#FF9100"),
-        Color.parseColor("#FF3D00")
-      };
-
-  static final int[][] ACCENT_COLORS_SUB =
-      new int[][] {
-        new int[] {
-          Color.parseColor("#FF8A80"),
-          Color.parseColor("#FF5252"),
-          Color.parseColor("#FF1744"),
-          Color.parseColor("#D50000")
-        },
-        new int[] {
-          Color.parseColor("#FF80AB"),
-          Color.parseColor("#FF4081"),
-          Color.parseColor("#F50057"),
-          Color.parseColor("#C51162")
-        },
-        new int[] {
-          Color.parseColor("#EA80FC"),
-          Color.parseColor("#E040FB"),
-          Color.parseColor("#D500F9"),
-          Color.parseColor("#AA00FF")
-        },
-        new int[] {
-          Color.parseColor("#B388FF"),
-          Color.parseColor("#7C4DFF"),
-          Color.parseColor("#651FFF"),
-          Color.parseColor("#6200EA")
-        },
-        new int[] {
-          Color.parseColor("#8C9EFF"),
-          Color.parseColor("#536DFE"),
-          Color.parseColor("#3D5AFE"),
-          Color.parseColor("#304FFE")
-        },
-        new int[] {
-          Color.parseColor("#82B1FF"),
-          Color.parseColor("#448AFF"),
-          Color.parseColor("#2979FF"),
-          Color.parseColor("#2962FF")
-        },
-        new int[] {
-          Color.parseColor("#80D8FF"),
-          Color.parseColor("#40C4FF"),
-          Color.parseColor("#00B0FF"),
-          Color.parseColor("#0091EA")
-        },
-        new int[] {
-          Color.parseColor("#84FFFF"),
-          Color.parseColor("#18FFFF"),
-          Color.parseColor("#00E5FF"),
-          Color.parseColor("#00B8D4")
-        },
-        new int[] {
-          Color.parseColor("#A7FFEB"),
-          Color.parseColor("#64FFDA"),
-          Color.parseColor("#1DE9B6"),
-          Color.parseColor("#00BFA5")
-        },
-        new int[] {
-          Color.parseColor("#B9F6CA"),
-          Color.parseColor("#69F0AE"),
-          Color.parseColor("#00E676"),
-          Color.parseColor("#00C853")
-        },
-        new int[] {
-          Color.parseColor("#CCFF90"),
-          Color.parseColor("#B2FF59"),
-          Color.parseColor("#76FF03"),
-          Color.parseColor("#64DD17")
-        },
-        new int[] {
-          Color.parseColor("#F4FF81"),
-          Color.parseColor("#EEFF41"),
-          Color.parseColor("#C6FF00"),
-          Color.parseColor("#AEEA00")
-        },
-        new int[] {
-          Color.parseColor("#FFFF8D"),
-          Color.parseColor("#FFFF00"),
-          Color.parseColor("#FFEA00"),
-          Color.parseColor("#FFD600")
-        },
-        new int[] {
-          Color.parseColor("#FFE57F"),
-          Color.parseColor("#FFD740"),
-          Color.parseColor("#FFC400"),
-          Color.parseColor("#FFAB00")
-        },
-        new int[] {
-          Color.parseColor("#FFD180"),
-          Color.parseColor("#FFAB40"),
-          Color.parseColor("#FF9100"),
-          Color.parseColor("#FF6D00")
-        },
-        new int[] {
-          Color.parseColor("#FF9E80"),
-          Color.parseColor("#FF6E40"),
-          Color.parseColor("#FF3D00"),
-          Color.parseColor("#DD2C00")
-        }
-      };
-}

+ 0 - 27
commons/src/main/java/com/afollestad/materialdialogs/color/FillGridView.java

@@ -1,27 +0,0 @@
-package com.afollestad.materialdialogs.color;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.GridView;
-
-/** @author Aidan Follestad (afollestad) */
-public class FillGridView extends GridView {
-
-  public FillGridView(Context context) {
-    super(context);
-  }
-
-  public FillGridView(Context context, AttributeSet attrs) {
-    super(context, attrs);
-  }
-
-  public FillGridView(Context context, AttributeSet attrs, int defStyle) {
-    super(context, attrs, defStyle);
-  }
-
-  @Override
-  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
-    super.onMeasure(widthMeasureSpec, expandSpec);
-  }
-}

+ 0 - 2
commons/src/main/java/com/afollestad/materialdialogs/color/package-info.java

@@ -1,2 +0,0 @@
-@javax.annotation.ParametersAreNonnullByDefault
-package com.afollestad.materialdialogs.color;

+ 0 - 369
commons/src/main/java/com/afollestad/materialdialogs/folderselector/FileChooserDialog.java

@@ -1,369 +0,0 @@
-package com.afollestad.materialdialogs.folderselector;
-
-import static com.afollestad.materialdialogs.util.DialogUtils.checkNotNull;
-
-import android.Manifest;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Environment;
-import android.support.annotation.Nullable;
-import android.support.annotation.StringRes;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.content.ContextCompat;
-import android.view.View;
-import android.webkit.MimeTypeMap;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.afollestad.materialdialogs.commons.R;
-import java.io.File;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-@SuppressWarnings("unused")
-public class FileChooserDialog extends DialogFragment implements MaterialDialog.ListCallback {
-
-  private static final String DEFAULT_TAG = "[MD_FILE_SELECTOR]";
-
-  private File parentFolder;
-  private File[] parentContents;
-  private boolean canGoUp = true;
-  private FileCallback callback;
-
-  public FileChooserDialog() {}
-
-  CharSequence[] getContentsArray() {
-    if (parentContents == null) {
-      if (canGoUp) {
-        return new String[] {getBuilder().goUpLabel};
-      }
-      return new String[] {};
-    }
-    String[] results = new String[parentContents.length + (canGoUp ? 1 : 0)];
-    if (canGoUp) {
-      results[0] = getBuilder().goUpLabel;
-    }
-    for (int i = 0; i < parentContents.length; i++) {
-      results[canGoUp ? i + 1 : i] = parentContents[i].getName();
-    }
-    return results;
-  }
-
-  File[] listFiles(@Nullable String mimeType, @Nullable String[] extensions) {
-    File[] contents = parentFolder.listFiles();
-    List<File> results = new ArrayList<>();
-    if (contents != null) {
-      MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
-      for (File fi : contents) {
-        if (fi.isDirectory()) {
-          results.add(fi);
-        } else {
-          if (extensions != null) {
-            boolean found = false;
-            for (String ext : extensions) {
-              if (fi.getName().toLowerCase().endsWith(ext.toLowerCase())) {
-                found = true;
-                break;
-              }
-            }
-            if (found) {
-              results.add(fi);
-            }
-          } else if (mimeType != null) {
-            if (fileIsMimeType(fi, mimeType, mimeTypeMap)) {
-              results.add(fi);
-            }
-          }
-        }
-      }
-      Collections.sort(results, new FileSorter());
-      return results.toArray(new File[results.size()]);
-    }
-    return null;
-  }
-
-  boolean fileIsMimeType(File file, @Nullable String mimeType, MimeTypeMap mimeTypeMap) {
-    if (mimeType == null || mimeType.equals("*/*")) {
-      return true;
-    } else {
-      // get the file mime type
-      String filename = file.toURI().toString();
-      int dotPos = filename.lastIndexOf('.');
-      if (dotPos == -1) {
-        return false;
-      }
-      String fileExtension = filename.substring(dotPos + 1);
-      if (fileExtension.endsWith("json")) {
-        return mimeType.startsWith("application/json");
-      }
-      String fileType = mimeTypeMap.getMimeTypeFromExtension(fileExtension);
-      if (fileType == null) {
-        return false;
-      }
-      // check the 'type/subtype' pattern
-      if (fileType.equals(mimeType)) {
-        return true;
-      }
-      // check the 'type/*' pattern
-      int mimeTypeDelimiter = mimeType.lastIndexOf('/');
-      if (mimeTypeDelimiter == -1) {
-        return false;
-      }
-      String mimeTypeMainType = mimeType.substring(0, mimeTypeDelimiter);
-      String mimeTypeSubtype = mimeType.substring(mimeTypeDelimiter + 1);
-      if (!mimeTypeSubtype.equals("*")) {
-        return false;
-      }
-      int fileTypeDelimiter = fileType.lastIndexOf('/');
-      if (fileTypeDelimiter == -1) {
-        return false;
-      }
-      String fileTypeMainType = fileType.substring(0, fileTypeDelimiter);
-      if (fileTypeMainType.equals(mimeTypeMainType)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @SuppressWarnings("ConstantConditions")
-  @Override
-  public Dialog onCreateDialog(Bundle savedInstanceState) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
-        && ContextCompat.checkSelfPermission(
-                getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
-            != PackageManager.PERMISSION_GRANTED) {
-      return new MaterialDialog.Builder(getActivity())
-          .title(R.string.md_error_label)
-          .content(R.string.md_storage_perm_error)
-          .positiveText(android.R.string.ok)
-          .build();
-    }
-
-    if (getArguments() == null || !getArguments().containsKey("builder")) {
-      throw new IllegalStateException("You must create a FileChooserDialog using the Builder.");
-    }
-    if (!getArguments().containsKey("current_path")) {
-      getArguments().putString("current_path", getBuilder().initialPath);
-    }
-    parentFolder = new File(getArguments().getString("current_path"));
-    checkIfCanGoUp();
-    parentContents = listFiles(getBuilder().mimeType, getBuilder().extensions);
-    return new MaterialDialog.Builder(getActivity())
-        .title(parentFolder.getAbsolutePath())
-        .typeface(getBuilder().mediumFont, getBuilder().regularFont)
-        .items(getContentsArray())
-        .itemsCallback(this)
-        .onNegative(
-            new MaterialDialog.SingleButtonCallback() {
-              @Override
-              public void onClick(MaterialDialog dialog, DialogAction which) {
-                dialog.dismiss();
-              }
-            })
-        .autoDismiss(false)
-        .negativeText(getBuilder().cancelButton)
-        .build();
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    if (callback != null) {
-      callback.onFileChooserDismissed(this);
-    }
-  }
-
-  @Override
-  public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence s) {
-    if (canGoUp && i == 0) {
-      parentFolder = parentFolder.getParentFile();
-      if (parentFolder.getAbsolutePath().equals("/storage/emulated")) {
-        parentFolder = parentFolder.getParentFile();
-      }
-      canGoUp = parentFolder.getParent() != null;
-    } else {
-      parentFolder = parentContents[canGoUp ? i - 1 : i];
-      canGoUp = true;
-      if (parentFolder.getAbsolutePath().equals("/storage/emulated")) {
-        parentFolder = Environment.getExternalStorageDirectory();
-      }
-    }
-    if (parentFolder.isFile()) {
-      callback.onFileSelection(this, parentFolder);
-      dismiss();
-    } else {
-      parentContents = listFiles(getBuilder().mimeType, getBuilder().extensions);
-      MaterialDialog dialog = (MaterialDialog) getDialog();
-      dialog.setTitle(parentFolder.getAbsolutePath());
-      checkNotNull(getArguments(), "arguments")
-          .putString("current_path", parentFolder.getAbsolutePath());
-      dialog.setItems(getContentsArray());
-    }
-  }
-
-  private void checkIfCanGoUp() {
-    try {
-      canGoUp = parentFolder.getPath().split("/").length > 1;
-    } catch (IndexOutOfBoundsException e) {
-      canGoUp = false;
-    }
-  }
-
-  @Override
-  public void onAttach(Context context) {
-    super.onAttach(context);
-    if (getActivity() instanceof FileCallback) {
-      callback = (FileCallback) getActivity();
-    } else if (getTargetFragment() instanceof FileCallback) {
-      callback = (FileCallback) getTargetFragment();
-    } else {
-      throw new IllegalStateException(
-          "FileChooserDialog needs to be shown from an Activity/Fragment implementing FileCallback.");
-    }
-  }
-
-  public void show() {
-    final FragmentManager fragmentManager =
-        getBuilder().fragment != null
-            ? getBuilder().fragment.getChildFragmentManager()
-            : getBuilder().activity.getSupportFragmentManager();
-
-    final String tag = getBuilder().tag;
-    Fragment frag = fragmentManager.findFragmentByTag(tag);
-    if (frag != null) {
-      ((DialogFragment) frag).dismiss();
-      fragmentManager.beginTransaction().remove(frag).commit();
-    }
-
-    if (getBuilder().fragment != null) {
-      setTargetFragment(getBuilder().fragment, 65);
-    }
-    show(fragmentManager, tag);
-  }
-
-  public String getInitialPath() {
-    return getBuilder().initialPath;
-  }
-
-  private Builder getBuilder() {
-    return (Builder) checkNotNull(getArguments(), "arguments").getSerializable("builder");
-  }
-
-  public interface FileCallback {
-
-    void onFileSelection(FileChooserDialog dialog, File file);
-
-    void onFileChooserDismissed(FileChooserDialog dialog);
-  }
-
-  public static class Builder implements Serializable {
-
-    transient FragmentActivity activity;
-    transient Fragment fragment;
-
-    @StringRes int cancelButton;
-    String initialPath;
-    String mimeType;
-    String[] extensions;
-    String tag;
-    String goUpLabel;
-    @Nullable String mediumFont;
-    @Nullable String regularFont;
-
-    private Builder() {
-      cancelButton = android.R.string.cancel;
-      initialPath = Environment.getExternalStorageDirectory().getAbsolutePath();
-      mimeType = null;
-      goUpLabel = "...";
-    }
-
-    public <T extends FragmentActivity & FileCallback> Builder(T activity) {
-      this();
-      this.activity = activity;
-    }
-
-    public <T extends Fragment & FileCallback> Builder(T fragment) {
-      this();
-      this.fragment = fragment;
-    }
-
-    public Builder typeface(@Nullable String medium, @Nullable String regular) {
-      this.mediumFont = medium;
-      this.regularFont = regular;
-      return this;
-    }
-
-    public Builder cancelButton(@StringRes int text) {
-      cancelButton = text;
-      return this;
-    }
-
-    public Builder initialPath(@Nullable String initialPath) {
-      if (initialPath == null) {
-        initialPath = File.separator;
-      }
-      this.initialPath = initialPath;
-      return this;
-    }
-
-    public Builder mimeType(@Nullable String type) {
-      mimeType = type;
-      return this;
-    }
-
-    public Builder extensionsFilter(@Nullable String... extensions) {
-      this.extensions = extensions;
-      return this;
-    }
-
-    public Builder tag(@Nullable String tag) {
-      if (tag == null) {
-        tag = DEFAULT_TAG;
-      }
-      this.tag = tag;
-      return this;
-    }
-
-    public Builder goUpLabel(String text) {
-      goUpLabel = text;
-      return this;
-    }
-
-    public FileChooserDialog build() {
-      FileChooserDialog dialog = new FileChooserDialog();
-      Bundle args = new Bundle();
-      args.putSerializable("builder", this);
-      dialog.setArguments(args);
-      return dialog;
-    }
-
-    public FileChooserDialog show() {
-      FileChooserDialog dialog = build();
-      dialog.show();
-      return dialog;
-    }
-  }
-
-  private static class FileSorter implements Comparator<File> {
-    @Override
-    public int compare(File lhs, File rhs) {
-      if (lhs.isDirectory() && !rhs.isDirectory()) {
-        return -1;
-      } else if (!lhs.isDirectory() && rhs.isDirectory()) {
-        return 1;
-      } else {
-        return lhs.getName().compareTo(rhs.getName());
-      }
-    }
-  }
-}

+ 0 - 350
commons/src/main/java/com/afollestad/materialdialogs/folderselector/FolderChooserDialog.java

@@ -1,350 +0,0 @@
-package com.afollestad.materialdialogs.folderselector;
-
-import static com.afollestad.materialdialogs.util.DialogUtils.checkNotNull;
-
-import android.Manifest;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Environment;
-import android.support.annotation.Nullable;
-import android.support.annotation.StringRes;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.view.View;
-import android.widget.Toast;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.afollestad.materialdialogs.commons.R;
-import java.io.File;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/** @author Aidan Follestad (afollestad) */
-public class FolderChooserDialog extends DialogFragment implements MaterialDialog.ListCallback {
-
-  private static final String DEFAULT_TAG = "[MD_FOLDER_SELECTOR]";
-
-  private File parentFolder;
-  private File[] parentContents;
-  private boolean canGoUp = false;
-  private FolderCallback callback;
-
-  public FolderChooserDialog() {}
-
-  String[] getContentsArray() {
-    if (parentContents == null) {
-      if (canGoUp) {
-        return new String[] {getBuilder().goUpLabel};
-      }
-      return new String[] {};
-    }
-    String[] results = new String[parentContents.length + (canGoUp ? 1 : 0)];
-    if (canGoUp) {
-      results[0] = getBuilder().goUpLabel;
-    }
-    for (int i = 0; i < parentContents.length; i++) {
-      results[canGoUp ? i + 1 : i] = parentContents[i].getName();
-    }
-    return results;
-  }
-
-  File[] listFiles() {
-    File[] contents = parentFolder.listFiles();
-    List<File> results = new ArrayList<>();
-    if (contents != null) {
-      for (File fi : contents) {
-        if (fi.isDirectory()) {
-          results.add(fi);
-        }
-      }
-      Collections.sort(results, new FolderSorter());
-      return results.toArray(new File[results.size()]);
-    }
-    return null;
-  }
-
-  @SuppressWarnings("ConstantConditions")
-  @Override
-  public Dialog onCreateDialog(Bundle savedInstanceState) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
-        && ActivityCompat.checkSelfPermission(
-                getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
-            != PackageManager.PERMISSION_GRANTED) {
-      return new MaterialDialog.Builder(getActivity())
-          .title(R.string.md_error_label)
-          .content(R.string.md_storage_perm_error)
-          .positiveText(android.R.string.ok)
-          .build();
-    }
-    if (getArguments() == null || !getArguments().containsKey("builder")) {
-      throw new IllegalStateException("You must create a FolderChooserDialog using the Builder.");
-    }
-    if (!getArguments().containsKey("current_path")) {
-      getArguments().putString("current_path", getBuilder().initialPath);
-    }
-    parentFolder = new File(getArguments().getString("current_path"));
-    checkIfCanGoUp();
-    parentContents = listFiles();
-    MaterialDialog.Builder builder =
-        new MaterialDialog.Builder(getActivity())
-            .typeface(getBuilder().mediumFont, getBuilder().regularFont)
-            .title(parentFolder.getAbsolutePath())
-            .items((CharSequence[]) getContentsArray())
-            .itemsCallback(this)
-            .onPositive(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    dialog.dismiss();
-                    callback.onFolderSelection(FolderChooserDialog.this, parentFolder);
-                  }
-                })
-            .onNegative(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    dialog.dismiss();
-                  }
-                })
-            .autoDismiss(false)
-            .positiveText(getBuilder().chooseButton)
-            .negativeText(getBuilder().cancelButton);
-    if (getBuilder().allowNewFolder) {
-      builder.neutralText(getBuilder().newFolderButton);
-      builder.onNeutral(
-          new MaterialDialog.SingleButtonCallback() {
-            @Override
-            public void onClick(MaterialDialog dialog, DialogAction which) {
-              createNewFolder();
-            }
-          });
-    }
-    if ("/".equals(getBuilder().initialPath)) {
-      canGoUp = false;
-    }
-    return builder.build();
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    if (callback != null) {
-      callback.onFolderChooserDismissed(this);
-    }
-  }
-
-  private void createNewFolder() {
-    new MaterialDialog.Builder(checkNotNull(getActivity(), "activity"))
-        .title(getBuilder().newFolderButton)
-        .input(
-            0,
-            0,
-            false,
-            new MaterialDialog.InputCallback() {
-              @Override
-              public void onInput(MaterialDialog dialog, CharSequence input) {
-                //noinspection ResultOfMethodCallIgnored
-                final File newFi = new File(parentFolder, input.toString());
-                if (!newFi.mkdir()) {
-                  String msg =
-                      "Unable to create folder "
-                          + newFi.getAbsolutePath()
-                          + ", make sure you have the WRITE_EXTERNAL_STORAGE permission or root permissions.";
-                  Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
-                } else {
-                  reload();
-                }
-              }
-            })
-        .show();
-  }
-
-  @Override
-  public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence s) {
-    if (canGoUp && i == 0) {
-      parentFolder = parentFolder.getParentFile();
-      if (parentFolder.getAbsolutePath().equals("/storage/emulated")) {
-        parentFolder = parentFolder.getParentFile();
-      }
-      canGoUp = parentFolder.getParent() != null;
-    } else {
-      parentFolder = parentContents[canGoUp ? i - 1 : i];
-      canGoUp = true;
-      if (parentFolder.getAbsolutePath().equals("/storage/emulated")) {
-        parentFolder = Environment.getExternalStorageDirectory();
-      }
-    }
-    reload();
-  }
-
-  private void checkIfCanGoUp() {
-    try {
-      canGoUp = parentFolder.getPath().split("/").length > 1;
-    } catch (IndexOutOfBoundsException e) {
-      canGoUp = false;
-    }
-  }
-
-  private void reload() {
-    parentContents = listFiles();
-    MaterialDialog dialog = (MaterialDialog) getDialog();
-    dialog.setTitle(parentFolder.getAbsolutePath());
-    checkNotNull(getArguments(), "arguments")
-        .putString("current_path", parentFolder.getAbsolutePath());
-    dialog.setItems((CharSequence[]) getContentsArray());
-  }
-
-  @Override
-  public void onAttach(Context context) {
-    super.onAttach(context);
-    if (getActivity() instanceof FolderCallback) {
-      callback = (FolderCallback) getActivity();
-    } else if (getTargetFragment() instanceof FolderCallback) {
-      callback = (FolderCallback) getTargetFragment();
-    } else {
-      throw new IllegalStateException(
-          "FolderChooserDialog needs to be shown from an Activity/Fragment implementing FolderCallback.");
-    }
-  }
-
-  public void show() {
-    final FragmentManager fragmentManager =
-        getBuilder().fragment != null
-            ? getBuilder().fragment.getChildFragmentManager()
-            : getBuilder().activity.getSupportFragmentManager();
-
-    final String tag = getBuilder().tag;
-    Fragment frag = fragmentManager.findFragmentByTag(tag);
-    if (frag != null) {
-      ((DialogFragment) frag).dismiss();
-      fragmentManager.beginTransaction().remove(frag).commit();
-    }
-
-    if (getBuilder().fragment != null) {
-      setTargetFragment(getBuilder().fragment, 63);
-    }
-    show(fragmentManager, tag);
-  }
-
-  private Builder getBuilder() {
-    return (Builder) checkNotNull(getArguments(), "arguments").getSerializable("builder");
-  }
-
-  public interface FolderCallback {
-
-    void onFolderSelection(FolderChooserDialog dialog, File folder);
-
-    void onFolderChooserDismissed(FolderChooserDialog dialog);
-  }
-
-  @SuppressWarnings({"unused", "SameParameterValue"})
-  public static class Builder implements Serializable {
-
-    transient FragmentActivity activity;
-    transient Fragment fragment;
-
-    @StringRes int chooseButton;
-    @StringRes int cancelButton;
-    String initialPath;
-    String tag;
-    boolean allowNewFolder;
-    @StringRes int newFolderButton;
-    String goUpLabel;
-    @Nullable String mediumFont;
-    @Nullable String regularFont;
-
-    private Builder() {
-      chooseButton = R.string.md_choose_label;
-      cancelButton = android.R.string.cancel;
-      goUpLabel = "...";
-      initialPath = Environment.getExternalStorageDirectory().getAbsolutePath();
-    }
-
-    public <T extends FragmentActivity & FolderCallback> Builder(T activity) {
-      this();
-      this.activity = activity;
-    }
-
-    public <T extends Fragment & FolderCallback> Builder(T fragment) {
-      this();
-      this.fragment = fragment;
-    }
-
-    public Builder typeface(@Nullable String medium, @Nullable String regular) {
-      this.mediumFont = medium;
-      this.regularFont = regular;
-      return this;
-    }
-
-    public Builder chooseButton(@StringRes int text) {
-      chooseButton = text;
-      return this;
-    }
-
-    public Builder cancelButton(@StringRes int text) {
-      cancelButton = text;
-      return this;
-    }
-
-    public Builder goUpLabel(String text) {
-      goUpLabel = text;
-      return this;
-    }
-
-    public Builder allowNewFolder(boolean allow, @StringRes int buttonLabel) {
-      allowNewFolder = allow;
-      if (buttonLabel == 0) {
-        buttonLabel = R.string.new_folder;
-      }
-      newFolderButton = buttonLabel;
-      return this;
-    }
-
-    public Builder initialPath(@Nullable String initialPath) {
-      if (initialPath == null) {
-        initialPath = File.separator;
-      }
-      this.initialPath = initialPath;
-      return this;
-    }
-
-    public Builder tag(@Nullable String tag) {
-      if (tag == null) {
-        tag = DEFAULT_TAG;
-      }
-      this.tag = tag;
-      return this;
-    }
-
-    public FolderChooserDialog build() {
-      FolderChooserDialog dialog = new FolderChooserDialog();
-      Bundle args = new Bundle();
-      args.putSerializable("builder", this);
-      dialog.setArguments(args);
-      return dialog;
-    }
-
-    public FolderChooserDialog show() {
-      FolderChooserDialog dialog = build();
-      dialog.show();
-      return dialog;
-    }
-  }
-
-  private static class FolderSorter implements Comparator<File> {
-    @Override
-    public int compare(File lhs, File rhs) {
-      return lhs.getName().compareTo(rhs.getName());
-    }
-  }
-}

+ 0 - 2
commons/src/main/java/com/afollestad/materialdialogs/folderselector/package-info.java

@@ -1,2 +0,0 @@
-@javax.annotation.ParametersAreNonnullByDefault
-package com.afollestad.materialdialogs.folderselector;

+ 0 - 180
commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialDialogPreference.java

@@ -1,180 +0,0 @@
-package com.afollestad.materialdialogs.prefs;
-
-import android.annotation.TargetApi;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.preference.DialogPreference;
-import android.util.AttributeSet;
-import android.view.View;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-
-/** @author Aidan Follestad (afollestad) */
-public class MaterialDialogPreference extends DialogPreference {
-
-  private Context context;
-  private MaterialDialog dialog;
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialDialogPreference(Context context) {
-    super(context);
-    init(context, null);
-  }
-
-  public MaterialDialogPreference(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    init(context, attrs);
-  }
-
-  public MaterialDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialDialogPreference(
-      Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-    super(context, attrs, defStyleAttr, defStyleRes);
-    init(context, attrs);
-  }
-
-  private void init(Context context, AttributeSet attrs) {
-    this.context = context;
-    PrefUtil.setLayoutResource(context, this, attrs);
-  }
-
-  @Override
-  public Dialog getDialog() {
-    return dialog;
-  }
-
-  @Override
-  protected void showDialog(Bundle state) {
-    MaterialDialog.Builder builder =
-        new MaterialDialog.Builder(context)
-            .title(getDialogTitle())
-            .icon(getDialogIcon())
-            .dismissListener(this)
-            .onAny(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    switch (which) {
-                      default:
-                        MaterialDialogPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_POSITIVE);
-                        break;
-                      case NEUTRAL:
-                        MaterialDialogPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEUTRAL);
-                        break;
-                      case NEGATIVE:
-                        MaterialDialogPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEGATIVE);
-                        break;
-                    }
-                  }
-                })
-            .positiveText(getPositiveButtonText())
-            .negativeText(getNegativeButtonText())
-            .autoDismiss(true); // immediately close the dialog after selection
-
-    final View contentView = onCreateDialogView();
-    if (contentView != null) {
-      onBindDialogView(contentView);
-      builder.customView(contentView, false);
-    } else {
-      builder.content(getDialogMessage());
-    }
-
-    PrefUtil.registerOnActivityDestroyListener(this, this);
-
-    dialog = builder.build();
-    if (state != null) {
-      dialog.onRestoreInstanceState(state);
-    }
-    dialog.show();
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    PrefUtil.unregisterOnActivityDestroyListener(this, this);
-  }
-
-  @Override
-  public void onActivityDestroy() {
-    super.onActivityDestroy();
-    if (dialog != null && dialog.isShowing()) {
-      dialog.dismiss();
-    }
-  }
-
-  @Override
-  protected Parcelable onSaveInstanceState() {
-    final Parcelable superState = super.onSaveInstanceState();
-    Dialog dialog = getDialog();
-    if (dialog == null || !dialog.isShowing()) {
-      return superState;
-    }
-
-    final SavedState myState = new SavedState(superState);
-    myState.isDialogShowing = true;
-    myState.dialogBundle = dialog.onSaveInstanceState();
-    return myState;
-  }
-
-  @Override
-  protected void onRestoreInstanceState(Parcelable state) {
-    if (state == null || !state.getClass().equals(SavedState.class)) {
-      // Didn't save state for us in onSaveInstanceState
-      super.onRestoreInstanceState(state);
-      return;
-    }
-
-    SavedState myState = (SavedState) state;
-    super.onRestoreInstanceState(myState.getSuperState());
-    if (myState.isDialogShowing) {
-      showDialog(myState.dialogBundle);
-    }
-  }
-
-  // From DialogPreference
-  private static class SavedState extends BaseSavedState {
-
-    public static final Creator<SavedState> CREATOR =
-        new Creator<SavedState>() {
-          public SavedState createFromParcel(Parcel in) {
-            return new SavedState(in);
-          }
-
-          public SavedState[] newArray(int size) {
-            return new SavedState[size];
-          }
-        };
-    boolean isDialogShowing;
-    Bundle dialogBundle;
-
-    SavedState(Parcel source) {
-      super(source);
-      isDialogShowing = source.readInt() == 1;
-      dialogBundle = source.readBundle();
-    }
-
-    SavedState(Parcelable superState) {
-      super(superState);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-      super.writeToParcel(dest, flags);
-      dest.writeInt(isDialogShowing ? 1 : 0);
-      dest.writeBundle(dialogBundle);
-    }
-  }
-}

+ 0 - 267
commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialEditTextPreference.java

@@ -1,267 +0,0 @@
-package com.afollestad.materialdialogs.prefs;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.preference.EditTextPreference;
-import android.support.v7.widget.AppCompatEditText;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.afollestad.materialdialogs.MaterialDialog.Builder;
-import com.afollestad.materialdialogs.commons.R;
-import com.afollestad.materialdialogs.internal.MDTintHelper;
-import com.afollestad.materialdialogs.util.DialogUtils;
-
-/** @author Aidan Follestad (afollestad) */
-public class MaterialEditTextPreference extends EditTextPreference {
-
-  private int color = 0;
-  private MaterialDialog dialog;
-  private EditText editText;
-
-  public MaterialEditTextPreference(Context context) {
-    super(context);
-    init(context, null);
-  }
-
-  public MaterialEditTextPreference(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialEditTextPreference(
-      Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-    super(context, attrs, defStyleAttr, defStyleRes);
-    init(context, attrs);
-  }
-
-  private void init(Context context, AttributeSet attrs) {
-    PrefUtil.setLayoutResource(context, this, attrs);
-    int fallback;
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      fallback = DialogUtils.resolveColor(context, android.R.attr.colorAccent);
-    } else {
-      fallback = 0;
-    }
-    fallback = DialogUtils.resolveColor(context, R.attr.colorAccent, fallback);
-    color = DialogUtils.resolveColor(context, R.attr.md_widget_color, fallback);
-
-    editText = new AppCompatEditText(context, attrs);
-    // Give it an ID so it can be saved/restored
-    editText.setId(android.R.id.edit);
-    editText.setEnabled(true);
-  }
-
-  @Override
-  protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
-    ((ViewGroup) dialogView)
-        .addView(
-            editText,
-            new LinearLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-  }
-
-  @SuppressLint("MissingSuperCall")
-  @Override
-  protected void onBindDialogView(View view) {
-    EditText editText = this.editText;
-    editText.setText(getText());
-    // Initialize cursor to end of text
-    if (editText.getText().length() > 0) {
-      editText.setSelection(editText.length());
-    }
-    ViewParent oldParent = editText.getParent();
-    if (oldParent != view) {
-      if (oldParent != null) {
-        ((ViewGroup) oldParent).removeView(editText);
-      }
-      onAddEditTextToDialogView(view, editText);
-    }
-  }
-
-  @Override
-  protected void onDialogClosed(boolean positiveResult) {
-    if (positiveResult) {
-      String value = editText.getText().toString();
-      if (callChangeListener(value)) {
-        setText(value);
-      }
-    }
-  }
-
-  @Override
-  public EditText getEditText() {
-    return editText;
-  }
-
-  @Override
-  public Dialog getDialog() {
-    return dialog;
-  }
-
-  @Override
-  protected void showDialog(Bundle state) {
-    Builder mBuilder =
-        new MaterialDialog.Builder(getContext())
-            .title(getDialogTitle())
-            .icon(getDialogIcon())
-            .positiveText(getPositiveButtonText())
-            .negativeText(getNegativeButtonText())
-            .dismissListener(this)
-            .onAny(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    switch (which) {
-                      default:
-                        MaterialEditTextPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_POSITIVE);
-                        break;
-                      case NEUTRAL:
-                        MaterialEditTextPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEUTRAL);
-                        break;
-                      case NEGATIVE:
-                        MaterialEditTextPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEGATIVE);
-                        break;
-                    }
-                  }
-                })
-            .dismissListener(this);
-
-    @SuppressLint("InflateParams")
-    View layout = LayoutInflater.from(getContext()).inflate(R.layout.md_stub_inputpref, null);
-    onBindDialogView(layout);
-
-    MDTintHelper.setTint(editText, color);
-
-    TextView message = (TextView) layout.findViewById(android.R.id.message);
-    if (getDialogMessage() != null && getDialogMessage().toString().length() > 0) {
-      message.setVisibility(View.VISIBLE);
-      message.setText(getDialogMessage());
-    } else {
-      message.setVisibility(View.GONE);
-    }
-    mBuilder.customView(layout, false);
-
-    PrefUtil.registerOnActivityDestroyListener(this, this);
-
-    dialog = mBuilder.build();
-    if (state != null) {
-      dialog.onRestoreInstanceState(state);
-    }
-    requestInputMethod(dialog);
-
-    dialog.show();
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    PrefUtil.unregisterOnActivityDestroyListener(this, this);
-  }
-
-  /** Copied from DialogPreference.java */
-  private void requestInputMethod(Dialog dialog) {
-    Window window = dialog.getWindow();
-    if (window == null) {
-      return;
-    }
-    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
-  }
-
-  @Override
-  public void onActivityDestroy() {
-    super.onActivityDestroy();
-    if (dialog != null && dialog.isShowing()) {
-      dialog.dismiss();
-    }
-  }
-
-  @Override
-  protected Parcelable onSaveInstanceState() {
-    final Parcelable superState = super.onSaveInstanceState();
-    Dialog dialog = getDialog();
-    if (dialog == null || !dialog.isShowing()) {
-      return superState;
-    }
-
-    final SavedState myState = new SavedState(superState);
-    myState.isDialogShowing = true;
-    myState.dialogBundle = dialog.onSaveInstanceState();
-    return myState;
-  }
-
-  @Override
-  protected void onRestoreInstanceState(Parcelable state) {
-    if (state == null || !state.getClass().equals(SavedState.class)) {
-      // Didn't save state for us in onSaveInstanceState
-      super.onRestoreInstanceState(state);
-      return;
-    }
-
-    SavedState myState = (SavedState) state;
-    super.onRestoreInstanceState(myState.getSuperState());
-    if (myState.isDialogShowing) {
-      showDialog(myState.dialogBundle);
-    }
-  }
-
-  // From DialogPreference
-  private static class SavedState extends BaseSavedState {
-
-    public static final Parcelable.Creator<SavedState> CREATOR =
-        new Parcelable.Creator<SavedState>() {
-          public SavedState createFromParcel(Parcel in) {
-            return new SavedState(in);
-          }
-
-          public SavedState[] newArray(int size) {
-            return new SavedState[size];
-          }
-        };
-    boolean isDialogShowing;
-    Bundle dialogBundle;
-
-    SavedState(Parcel source) {
-      super(source);
-      isDialogShowing = source.readInt() == 1;
-      dialogBundle = source.readBundle();
-    }
-
-    SavedState(Parcelable superState) {
-      super(superState);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-      super.writeToParcel(dest, flags);
-      dest.writeInt(isDialogShowing ? 1 : 0);
-      dest.writeBundle(dialogBundle);
-    }
-  }
-}

+ 0 - 226
commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialListPreference.java

@@ -1,226 +0,0 @@
-package com.afollestad.materialdialogs.prefs;
-
-import android.annotation.TargetApi;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.preference.ListPreference;
-import android.support.v7.widget.RecyclerView;
-import android.util.AttributeSet;
-import android.view.View;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-import java.lang.reflect.Field;
-
-/** @author Marc Holder Kluver (marchold), Aidan Follestad (afollestad) */
-public class MaterialListPreference extends ListPreference {
-
-  private Context context;
-  private MaterialDialog dialog;
-
-  public MaterialListPreference(Context context) {
-    super(context);
-    init(context, null);
-  }
-
-  public MaterialListPreference(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialListPreference(
-      Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-    super(context, attrs, defStyleAttr, defStyleRes);
-    init(context, attrs);
-  }
-
-  private void init(Context context, AttributeSet attrs) {
-    this.context = context;
-    PrefUtil.setLayoutResource(context, this, attrs);
-    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
-      setWidgetLayoutResource(0);
-    }
-  }
-
-  @Override
-  public void setEntries(CharSequence[] entries) {
-    super.setEntries(entries);
-    if (dialog != null) {
-      dialog.setItems(entries);
-    }
-  }
-
-  @Override
-  public Dialog getDialog() {
-    return dialog;
-  }
-
-  public RecyclerView getRecyclerView() {
-    if (getDialog() == null) {
-      return null;
-    }
-    return ((MaterialDialog) getDialog()).getRecyclerView();
-  }
-
-  @Override
-  protected void showDialog(Bundle state) {
-    if (getEntries() == null || getEntryValues() == null) {
-      throw new IllegalStateException(
-          "ListPreference requires an entries array and an entryValues array.");
-    }
-
-    int preselect = findIndexOfValue(getValue());
-    MaterialDialog.Builder builder =
-        new MaterialDialog.Builder(context)
-            .title(getDialogTitle())
-            .icon(getDialogIcon())
-            .dismissListener(this)
-            .onAny(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    switch (which) {
-                      default:
-                        MaterialListPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_POSITIVE);
-                        break;
-                      case NEUTRAL:
-                        MaterialListPreference.this.onClick(dialog, DialogInterface.BUTTON_NEUTRAL);
-                        break;
-                      case NEGATIVE:
-                        MaterialListPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEGATIVE);
-                        break;
-                    }
-                  }
-                })
-            .negativeText(getNegativeButtonText())
-            .items(getEntries())
-            .autoDismiss(true) // immediately close the dialog after selection
-            .itemsCallbackSingleChoice(
-                preselect,
-                new MaterialDialog.ListCallbackSingleChoice() {
-                  @Override
-                  public boolean onSelection(
-                      MaterialDialog dialog, View itemView, int which, CharSequence text) {
-                    onClick(null, DialogInterface.BUTTON_POSITIVE);
-                    if (which >= 0 && getEntryValues() != null) {
-                      try {
-                        Field clickedIndex =
-                            ListPreference.class.getDeclaredField("mClickedDialogEntryIndex");
-                        clickedIndex.setAccessible(true);
-                        clickedIndex.set(MaterialListPreference.this, which);
-                      } catch (Exception e) {
-                        e.printStackTrace();
-                      }
-                    }
-                    return true;
-                  }
-                });
-
-    final View contentView = onCreateDialogView();
-    if (contentView != null) {
-      onBindDialogView(contentView);
-      builder.customView(contentView, false);
-    } else {
-      builder.content(getDialogMessage());
-    }
-
-    PrefUtil.registerOnActivityDestroyListener(this, this);
-
-    dialog = builder.build();
-    if (state != null) {
-      dialog.onRestoreInstanceState(state);
-    }
-    onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
-    dialog.show();
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    PrefUtil.unregisterOnActivityDestroyListener(this, this);
-  }
-
-  @Override
-  public void onActivityDestroy() {
-    super.onActivityDestroy();
-    if (dialog != null && dialog.isShowing()) {
-      dialog.dismiss();
-    }
-  }
-
-  @Override
-  protected Parcelable onSaveInstanceState() {
-    final Parcelable superState = super.onSaveInstanceState();
-    Dialog dialog = getDialog();
-    if (dialog == null || !dialog.isShowing()) {
-      return superState;
-    }
-
-    final SavedState myState = new SavedState(superState);
-    myState.isDialogShowing = true;
-    myState.dialogBundle = dialog.onSaveInstanceState();
-    return myState;
-  }
-
-  @Override
-  protected void onRestoreInstanceState(Parcelable state) {
-    if (state == null || !state.getClass().equals(SavedState.class)) {
-      // Didn't save state for us in onSaveInstanceState
-      super.onRestoreInstanceState(state);
-      return;
-    }
-
-    SavedState myState = (SavedState) state;
-    super.onRestoreInstanceState(myState.getSuperState());
-    if (myState.isDialogShowing) {
-      showDialog(myState.dialogBundle);
-    }
-  }
-
-  // From DialogPreference
-  private static class SavedState extends BaseSavedState {
-
-    public static final Parcelable.Creator<SavedState> CREATOR =
-        new Parcelable.Creator<SavedState>() {
-          public SavedState createFromParcel(Parcel in) {
-            return new SavedState(in);
-          }
-
-          public SavedState[] newArray(int size) {
-            return new SavedState[size];
-          }
-        };
-    boolean isDialogShowing;
-    Bundle dialogBundle;
-
-    SavedState(Parcel source) {
-      super(source);
-      isDialogShowing = source.readInt() == 1;
-      dialogBundle = source.readBundle();
-    }
-
-    SavedState(Parcelable superState) {
-      super(superState);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-      super.writeToParcel(dest, flags);
-      dest.writeInt(isDialogShowing ? 1 : 0);
-      dest.writeBundle(dialogBundle);
-    }
-  }
-}

+ 0 - 225
commons/src/main/java/com/afollestad/materialdialogs/prefs/MaterialMultiSelectListPreference.java

@@ -1,225 +0,0 @@
-package com.afollestad.materialdialogs.prefs;
-
-import android.annotation.TargetApi;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.preference.MultiSelectListPreference;
-import android.util.AttributeSet;
-import android.view.View;
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class only works on Honeycomb (API 11) and above.
- *
- * @author Aidan Follestad (afollestad)
- */
-@TargetApi(Build.VERSION_CODES.HONEYCOMB)
-public class MaterialMultiSelectListPreference extends MultiSelectListPreference {
-
-  private Context context;
-  private MaterialDialog mDialog;
-
-  public MaterialMultiSelectListPreference(Context context) {
-    super(context);
-    init(context, null);
-  }
-
-  public MaterialMultiSelectListPreference(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    init(context, attrs);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MaterialMultiSelectListPreference(
-      Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-    super(context, attrs, defStyleAttr, defStyleRes);
-    init(context, attrs);
-  }
-
-  @Override
-  public void setEntries(CharSequence[] entries) {
-    super.setEntries(entries);
-    if (mDialog != null) {
-      mDialog.setItems(entries);
-    }
-  }
-
-  private void init(Context context, AttributeSet attrs) {
-    this.context = context;
-    PrefUtil.setLayoutResource(context, this, attrs);
-    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
-      setWidgetLayoutResource(0);
-    }
-  }
-
-  @Override
-  public Dialog getDialog() {
-    return mDialog;
-  }
-
-  @Override
-  protected void showDialog(Bundle state) {
-    List<Integer> indices = new ArrayList<>();
-    for (String s : getValues()) {
-      int index = findIndexOfValue(s);
-      if (index >= 0) {
-        indices.add(findIndexOfValue(s));
-      }
-    }
-    MaterialDialog.Builder builder =
-        new MaterialDialog.Builder(context)
-            .title(getDialogTitle())
-            .icon(getDialogIcon())
-            .negativeText(getNegativeButtonText())
-            .positiveText(getPositiveButtonText())
-            .onAny(
-                new MaterialDialog.SingleButtonCallback() {
-                  @Override
-                  public void onClick(MaterialDialog dialog, DialogAction which) {
-                    switch (which) {
-                      default:
-                        MaterialMultiSelectListPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_POSITIVE);
-                        break;
-                      case NEUTRAL:
-                        MaterialMultiSelectListPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEUTRAL);
-                        break;
-                      case NEGATIVE:
-                        MaterialMultiSelectListPreference.this.onClick(
-                            dialog, DialogInterface.BUTTON_NEGATIVE);
-                        break;
-                    }
-                  }
-                })
-            .items(getEntries())
-            .itemsCallbackMultiChoice(
-                indices.toArray(new Integer[indices.size()]),
-                new MaterialDialog.ListCallbackMultiChoice() {
-                  @Override
-                  public boolean onSelection(
-                      MaterialDialog dialog, Integer[] which, CharSequence[] text) {
-                    onClick(null, DialogInterface.BUTTON_POSITIVE);
-                    dialog.dismiss();
-                    final Set<String> values = new HashSet<>();
-                    for (int i : which) {
-                      values.add(getEntryValues()[i].toString());
-                    }
-                    if (callChangeListener(values)) {
-                      setValues(values);
-                    }
-                    return true;
-                  }
-                })
-            .dismissListener(this);
-
-    final View contentView = onCreateDialogView();
-    if (contentView != null) {
-      onBindDialogView(contentView);
-      builder.customView(contentView, false);
-    } else {
-      builder.content(getDialogMessage());
-    }
-
-    PrefUtil.registerOnActivityDestroyListener(this, this);
-
-    mDialog = builder.build();
-    if (state != null) {
-      mDialog.onRestoreInstanceState(state);
-    }
-    mDialog.show();
-  }
-
-  @Override
-  public void onDismiss(DialogInterface dialog) {
-    super.onDismiss(dialog);
-    PrefUtil.unregisterOnActivityDestroyListener(this, this);
-  }
-
-  @Override
-  public void onActivityDestroy() {
-    super.onActivityDestroy();
-    if (mDialog != null && mDialog.isShowing()) {
-      mDialog.dismiss();
-    }
-  }
-
-  @Override
-  protected Parcelable onSaveInstanceState() {
-    final Parcelable superState = super.onSaveInstanceState();
-    Dialog dialog = getDialog();
-    if (dialog == null || !dialog.isShowing()) {
-      return superState;
-    }
-
-    final SavedState myState = new SavedState(superState);
-    myState.isDialogShowing = true;
-    myState.dialogBundle = dialog.onSaveInstanceState();
-    return myState;
-  }
-
-  @Override
-  protected void onRestoreInstanceState(Parcelable state) {
-    if (state == null || !state.getClass().equals(SavedState.class)) {
-      // Didn't save state for us in onSaveInstanceState
-      super.onRestoreInstanceState(state);
-      return;
-    }
-
-    SavedState myState = (SavedState) state;
-    super.onRestoreInstanceState(myState.getSuperState());
-    if (myState.isDialogShowing) {
-      showDialog(myState.dialogBundle);
-    }
-  }
-
-  // From DialogPreference
-  private static class SavedState extends BaseSavedState {
-
-    public static final Parcelable.Creator<SavedState> CREATOR =
-        new Parcelable.Creator<SavedState>() {
-          public SavedState createFromParcel(Parcel in) {
-            return new SavedState(in);
-          }
-
-          public SavedState[] newArray(int size) {
-            return new SavedState[size];
-          }
-        };
-    boolean isDialogShowing;
-    Bundle dialogBundle;
-
-    SavedState(Parcel source) {
-      super(source);
-      isDialogShowing = source.readInt() == 1;
-      dialogBundle = source.readBundle();
-    }
-
-    SavedState(Parcelable superState) {
-      super(superState);
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-      super.writeToParcel(dest, flags);
-      dest.writeInt(isDialogShowing ? 1 : 0);
-      dest.writeBundle(dialogBundle);
-    }
-  }
-}

+ 0 - 76
commons/src/main/java/com/afollestad/materialdialogs/prefs/PrefUtil.java

@@ -1,76 +0,0 @@
-package com.afollestad.materialdialogs.prefs;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.preference.Preference;
-import android.preference.PreferenceManager;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import com.afollestad.materialdialogs.commons.R;
-import java.lang.reflect.Method;
-
-/** @author Aidan Follestad (afollestad) */
-class PrefUtil {
-
-  private PrefUtil() {}
-
-  static void setLayoutResource(
-      Context context, Preference preference, @Nullable AttributeSet attrs) {
-    boolean foundLayout = false;
-    if (attrs != null) {
-      for (int i = 0; i < attrs.getAttributeCount(); i++) {
-        final String namespace = ((XmlResourceParser) attrs).getAttributeNamespace(0);
-        if (namespace.equals("http://schemas.android.com/apk/res/android")
-            && attrs.getAttributeName(i).equals("layout")) {
-          foundLayout = true;
-          break;
-        }
-      }
-    }
-
-    boolean useStockLayout = false;
-    if (attrs != null) {
-      TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.Preference, 0, 0);
-      try {
-        useStockLayout = a.getBoolean(R.styleable.Preference_useStockLayout, false);
-      } finally {
-        a.recycle();
-      }
-    }
-
-    if (!foundLayout && !useStockLayout) {
-      preference.setLayoutResource(R.layout.md_preference_custom);
-    }
-  }
-
-  static void registerOnActivityDestroyListener(
-      Preference preference, PreferenceManager.OnActivityDestroyListener listener) {
-    try {
-      PreferenceManager pm = preference.getPreferenceManager();
-      Method method =
-          pm.getClass()
-              .getDeclaredMethod(
-                  "registerOnActivityDestroyListener",
-                  PreferenceManager.OnActivityDestroyListener.class);
-      method.setAccessible(true);
-      method.invoke(pm, listener);
-    } catch (Exception ignored) {
-    }
-  }
-
-  static void unregisterOnActivityDestroyListener(
-      Preference preference, PreferenceManager.OnActivityDestroyListener listener) {
-    try {
-      PreferenceManager pm = preference.getPreferenceManager();
-      Method method =
-          pm.getClass()
-              .getDeclaredMethod(
-                  "unregisterOnActivityDestroyListener",
-                  PreferenceManager.OnActivityDestroyListener.class);
-      method.setAccessible(true);
-      method.invoke(pm, listener);
-    } catch (Exception ignored) {
-    }
-  }
-}

+ 0 - 2
commons/src/main/java/com/afollestad/materialdialogs/prefs/package-info.java

@@ -1,2 +0,0 @@
-@javax.annotation.ParametersAreNonnullByDefault
-package com.afollestad.materialdialogs.prefs;

+ 0 - 118
commons/src/main/java/com/afollestad/materialdialogs/simplelist/MaterialSimpleListAdapter.java

@@ -1,118 +0,0 @@
-package com.afollestad.materialdialogs.simplelist;
-
-import android.graphics.PorterDuff;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.MaterialDialog;
-import com.afollestad.materialdialogs.commons.R;
-import com.afollestad.materialdialogs.internal.MDAdapter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * See the sample project to understand how this is used. Mimics the Simple List dialog style
- * displayed on Google's guidelines site:
- * https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs
- *
- * @author Aidan Follestad (afollestad)
- */
-public class MaterialSimpleListAdapter
-    extends RecyclerView.Adapter<MaterialSimpleListAdapter.SimpleListVH> implements MDAdapter {
-
-  private MaterialDialog dialog;
-  private List<MaterialSimpleListItem> items;
-  private Callback callback;
-
-  public MaterialSimpleListAdapter(Callback callback) {
-    items = new ArrayList<>(4);
-    this.callback = callback;
-  }
-
-  public void add(MaterialSimpleListItem item) {
-    items.add(item);
-    notifyItemInserted(items.size() - 1);
-  }
-
-  public void clear() {
-    items.clear();
-    notifyDataSetChanged();
-  }
-
-  public MaterialSimpleListItem getItem(int index) {
-    return items.get(index);
-  }
-
-  @Override
-  public void setDialog(MaterialDialog dialog) {
-    this.dialog = dialog;
-  }
-
-  @Override
-  public SimpleListVH onCreateViewHolder(ViewGroup parent, int viewType) {
-    final View view =
-        LayoutInflater.from(parent.getContext())
-            .inflate(R.layout.md_simplelist_item, parent, false);
-    return new SimpleListVH(view, this);
-  }
-
-  @Override
-  public void onBindViewHolder(SimpleListVH holder, int position) {
-    if (dialog != null) {
-      final MaterialSimpleListItem item = items.get(position);
-      if (item.getIcon() != null) {
-        holder.icon.setImageDrawable(item.getIcon());
-        holder.icon.setPadding(
-            item.getIconPadding(),
-            item.getIconPadding(),
-            item.getIconPadding(),
-            item.getIconPadding());
-        holder
-            .icon
-            .getBackground()
-            .setColorFilter(item.getBackgroundColor(), PorterDuff.Mode.SRC_ATOP);
-      } else {
-        holder.icon.setVisibility(View.GONE);
-      }
-      holder.title.setTextColor(dialog.getBuilder().getItemColor());
-      holder.title.setText(item.getContent());
-      dialog.setTypeface(holder.title, dialog.getBuilder().getRegularFont());
-    }
-  }
-
-  @Override
-  public int getItemCount() {
-    return items.size();
-  }
-
-  public interface Callback {
-
-    void onMaterialListItemSelected(MaterialDialog dialog, int index, MaterialSimpleListItem item);
-  }
-
-  static class SimpleListVH extends RecyclerView.ViewHolder implements View.OnClickListener {
-
-    final ImageView icon;
-    final TextView title;
-    final MaterialSimpleListAdapter adapter;
-
-    SimpleListVH(View itemView, MaterialSimpleListAdapter adapter) {
-      super(itemView);
-      icon = (ImageView) itemView.findViewById(android.R.id.icon);
-      title = (TextView) itemView.findViewById(android.R.id.title);
-      this.adapter = adapter;
-      itemView.setOnClickListener(this);
-    }
-
-    @Override
-    public void onClick(View view) {
-      if (adapter.callback != null) {
-        adapter.callback.onMaterialListItemSelected(
-            adapter.dialog, getAdapterPosition(), adapter.getItem(getAdapterPosition()));
-      }
-    }
-  }
-}

+ 0 - 142
commons/src/main/java/com/afollestad/materialdialogs/simplelist/MaterialSimpleListItem.java

@@ -1,142 +0,0 @@
-package com.afollestad.materialdialogs.simplelist;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.AttrRes;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.annotation.DimenRes;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IntRange;
-import android.support.annotation.Nullable;
-import android.support.annotation.StringRes;
-import android.support.v4.content.ContextCompat;
-import android.util.TypedValue;
-import com.afollestad.materialdialogs.util.DialogUtils;
-
-/** @author Aidan Follestad (afollestad) */
-public class MaterialSimpleListItem {
-
-  private final Builder builder;
-
-  private MaterialSimpleListItem(Builder builder) {
-    this.builder = builder;
-  }
-
-  public Drawable getIcon() {
-    return builder.icon;
-  }
-
-  public CharSequence getContent() {
-    return builder.content;
-  }
-
-  public int getIconPadding() {
-    return builder.iconPadding;
-  }
-
-  @ColorInt
-  public int getBackgroundColor() {
-    return builder.backgroundColor;
-  }
-
-  public long getId() {
-    return builder.id;
-  }
-
-  @Nullable
-  public Object getTag() {
-    return builder.tag;
-  }
-
-  @Override
-  public String toString() {
-    if (getContent() != null) {
-      return getContent().toString();
-    } else {
-      return "(no content)";
-    }
-  }
-
-  public static class Builder {
-
-    private final Context context;
-    protected Drawable icon;
-    protected CharSequence content;
-    protected long id;
-
-    int iconPadding;
-    int backgroundColor;
-    Object tag;
-
-    public Builder(Context context) {
-      this.context = context;
-      backgroundColor = Color.parseColor("#BCBCBC");
-    }
-
-    public Builder icon(Drawable icon) {
-      this.icon = icon;
-      return this;
-    }
-
-    public Builder icon(@DrawableRes int iconRes) {
-      return icon(ContextCompat.getDrawable(context, iconRes));
-    }
-
-    public Builder iconPadding(@IntRange(from = 0, to = Integer.MAX_VALUE) int padding) {
-      this.iconPadding = padding;
-      return this;
-    }
-
-    public Builder iconPaddingDp(@IntRange(from = 0, to = Integer.MAX_VALUE) int paddingDp) {
-      this.iconPadding =
-          (int)
-              TypedValue.applyDimension(
-                  TypedValue.COMPLEX_UNIT_DIP,
-                  paddingDp,
-                  context.getResources().getDisplayMetrics());
-      return this;
-    }
-
-    public Builder iconPaddingRes(@DimenRes int paddingRes) {
-      return iconPadding(context.getResources().getDimensionPixelSize(paddingRes));
-    }
-
-    public Builder content(CharSequence content) {
-      this.content = content;
-      return this;
-    }
-
-    public Builder content(@StringRes int contentRes) {
-      return content(context.getString(contentRes));
-    }
-
-    public Builder backgroundColor(@ColorInt int color) {
-      this.backgroundColor = color;
-      return this;
-    }
-
-    public Builder backgroundColorRes(@ColorRes int colorRes) {
-      return backgroundColor(DialogUtils.getColor(context, colorRes));
-    }
-
-    public Builder backgroundColorAttr(@AttrRes int colorAttr) {
-      return backgroundColor(DialogUtils.resolveColor(context, colorAttr));
-    }
-
-    public Builder id(long id) {
-      this.id = id;
-      return this;
-    }
-
-    public Builder tag(@Nullable Object tag) {
-      this.tag = tag;
-      return this;
-    }
-
-    public MaterialSimpleListItem build() {
-      return new MaterialSimpleListItem(this);
-    }
-  }
-}

+ 0 - 2
commons/src/main/java/com/afollestad/materialdialogs/simplelist/package-info.java

@@ -1,2 +0,0 @@
-@javax.annotation.ParametersAreNonnullByDefault
-package com.afollestad.materialdialogs.simplelist;

+ 0 - 8
commons/src/main/res/drawable/gray_circle.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-  android:shape="oval">
-  <solid android:color="#BCBCBC" />
-  <size
-    android:width="@dimen/md_simplelist_icon"
-    android:height="@dimen/md_simplelist_icon" />
-</shape>

+ 0 - 19
commons/src/main/res/layout/md_dialog_colorchooser.xml

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent">
-
-  <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <include layout="@layout/md_stub_colorchooser_grid" />
-
-    <include
-      layout="@layout/md_stub_colorchooser_custom"
-      android:visibility="gone" />
-
-  </FrameLayout>
-
-</ScrollView>

+ 0 - 74
commons/src/main/res/layout/md_preference_custom.xml

@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:tools="http://schemas.android.com/tools"
-  android:layout_width="match_parent"
-  android:layout_height="wrap_content"
-  android:baselineAligned="false"
-  android:gravity="center_vertical"
-  android:minHeight="?android:attr/listPreferredItemHeight"
-  android:orientation="horizontal"
-  android:paddingEnd="?android:attr/scrollbarSize"
-  android:paddingRight="?android:attr/scrollbarSize"
-  tools:ignore="RtlSymmetry,UnusedAttribute">
-
-  <ImageView
-    android:id="@android:id/icon"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:layout_marginLeft="@dimen/md_preference_content_inset"
-    android:layout_marginStart="@dimen/md_preference_content_inset"
-    tools:ignore="ContentDescription" />
-
-  <RelativeLayout
-    android:layout_width="0dp"
-    android:layout_height="wrap_content"
-    android:layout_gravity="left|start|center_vertical"
-    android:layout_marginBottom="12dip"
-    android:layout_marginEnd="6dip"
-    android:layout_marginLeft="@dimen/md_preference_content_inset"
-    android:layout_marginRight="6dip"
-    android:layout_marginStart="@dimen/md_preference_content_inset"
-    android:layout_marginTop="12dip"
-    android:layout_weight="1">
-
-    <TextView
-      android:id="@android:id/title"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignParentLeft="true"
-      android:layout_alignParentStart="true"
-      android:ellipsize="marquee"
-      android:fadingEdge="horizontal"
-      android:fontFamily="sans-serif"
-      android:lines="1"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="16sp"
-      tools:text="Title" />
-
-    <TextView
-      android:id="@android:id/summary"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignLeft="@android:id/title"
-      android:layout_alignStart="@android:id/title"
-      android:layout_below="@android:id/title"
-      android:layout_marginTop="2dp"
-      android:fontFamily="sans-serif"
-      android:maxLines="4"
-      android:textColor="?android:textColorSecondary"
-      android:textSize="14sp"
-      tools:text="Summary" />
-
-  </RelativeLayout>
-
-  <!-- Preference should place its actual preference widget here. -->
-  <LinearLayout
-    android:id="@android:id/widget_frame"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:layout_gravity="end|right|center_vertical"
-    android:gravity="center_vertical"
-    android:orientation="vertical" />
-
-</LinearLayout>

+ 0 - 36
commons/src/main/res/layout/md_simplelist_item.xml

@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:tools="http://schemas.android.com/tools"
-  android:layout_width="match_parent"
-  android:layout_height="wrap_content"
-  android:background="?selectableItemBackground"
-  android:focusable="true"
-  android:gravity="start|center_vertical"
-  android:minHeight="@dimen/md_simpleitem_height"
-  android:orientation="horizontal"
-  android:paddingEnd="@dimen/md_dialog_frame_margin"
-  android:paddingLeft="@dimen/md_dialog_frame_margin"
-  android:paddingRight="@dimen/md_dialog_frame_margin"
-  android:paddingStart="@dimen/md_dialog_frame_margin">
-
-  <ImageView
-    android:id="@android:id/icon"
-    android:layout_width="@dimen/md_simplelist_icon"
-    android:layout_height="@dimen/md_simplelist_icon"
-    android:layout_gravity="start|center_vertical"
-    android:layout_marginEnd="@dimen/md_simplelist_icon_margin"
-    android:layout_marginRight="@dimen/md_simplelist_icon_margin"
-    android:background="@drawable/gray_circle"
-    android:scaleType="fitXY"
-    tools:background="#f5f5f5"
-    tools:ignore="ContentDescription" />
-
-  <TextView
-    android:id="@android:id/title"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
-    android:textSize="@dimen/md_simplelist_textsize"
-    tools:text="Title" />
-
-</LinearLayout>

+ 0 - 235
commons/src/main/res/layout/md_stub_colorchooser_custom.xml

@@ -1,235 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:tools="http://schemas.android.com/tools"
-  android:id="@+id/md_colorChooserCustomFrame"
-  android:layout_width="match_parent"
-  android:layout_height="wrap_content"
-  android:orientation="vertical"
-  android:paddingBottom="@dimen/md_title_frame_margin_bottom"
-  android:paddingTop="@dimen/md_title_frame_margin_bottom">
-
-  <View
-    android:id="@+id/md_colorIndicator"
-    android:layout_width="match_parent"
-    android:layout_height="120dp"
-    tools:background="@color/md_material_blue_600" />
-
-  <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center_horizontal"
-    android:layout_marginTop="@dimen/md_title_frame_margin_bottom"
-    android:gravity="center">
-
-    <TextView
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_marginEnd="2dp"
-      android:layout_marginRight="2dp"
-      android:digits="0123456789abcdefABCDEF"
-      android:text="#"
-      android:textColor="?android:textColorPrimary"
-      android:textColorHint="?android:textColorSecondary"
-      android:textSize="@dimen/md_title_textsize"
-      tools:ignore="HardcodedText,TextViewEdits" />
-
-    <EditText
-      android:id="@+id/md_hexInput"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:digits="0123456789abcdefABCDEF"
-      android:focusable="true"
-      android:hint="FF0099CC"
-      android:textSize="@dimen/md_title_textsize"
-      tools:ignore="HardcodedText" />
-
-  </LinearLayout>
-
-  <RelativeLayout
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginTop="@dimen/md_title_frame_margin_bottom"
-    android:paddingLeft="@dimen/md_dialog_frame_margin"
-    android:paddingRight="@dimen/md_dialog_frame_margin">
-
-    <!-- Alpha -->
-
-    <TextView
-      android:id="@+id/md_colorALabel"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorA"
-      android:layout_alignTop="@+id/md_colorA"
-      android:layout_marginEnd="4dp"
-      android:layout_marginRight="4dp"
-      android:text="A"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <SeekBar
-      android:id="@+id/md_colorA"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_marginTop="@dimen/md_title_frame_margin_bottom"
-      android:layout_toEndOf="@+id/md_colorALabel"
-      android:layout_toLeftOf="@+id/md_colorAValue"
-      android:layout_toRightOf="@+id/md_colorALabel"
-      android:layout_toStartOf="@+id/md_colorAValue"
-      android:focusable="true"
-      android:max="255" />
-
-    <TextView
-      android:id="@+id/md_colorAValue"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorA"
-      android:layout_alignParentEnd="true"
-      android:layout_alignParentRight="true"
-      android:layout_alignTop="@+id/md_colorA"
-      android:layout_marginLeft="4dp"
-      android:layout_marginStart="4dp"
-      android:gravity="center"
-      android:minWidth="24dp"
-      android:text="0"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <!-- Red -->
-
-    <TextView
-      android:id="@+id/md_colorRLabel"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorR"
-      android:layout_alignTop="@+id/md_colorR"
-      android:layout_marginEnd="4dp"
-      android:layout_marginRight="4dp"
-      android:text="R"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <SeekBar
-      android:id="@+id/md_colorR"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_below="@+id/md_colorA"
-      android:layout_marginTop="@dimen/md_title_frame_margin_bottom"
-      android:layout_toEndOf="@+id/md_colorRLabel"
-      android:layout_toLeftOf="@+id/md_colorRValue"
-      android:layout_toRightOf="@+id/md_colorRLabel"
-      android:layout_toStartOf="@+id/md_colorRValue"
-      android:focusable="true"
-      android:max="255" />
-
-    <TextView
-      android:id="@+id/md_colorRValue"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorR"
-      android:layout_alignParentEnd="true"
-      android:layout_alignParentRight="true"
-      android:layout_alignTop="@+id/md_colorR"
-      android:layout_marginLeft="4dp"
-      android:layout_marginStart="4dp"
-      android:gravity="center"
-      android:minWidth="24dp"
-      android:text="0"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <!-- Green -->
-
-    <TextView
-      android:id="@+id/md_colorGLabel"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorG"
-      android:layout_alignTop="@+id/md_colorG"
-      android:layout_marginEnd="4dp"
-      android:layout_marginRight="4dp"
-      android:text="G"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <SeekBar
-      android:id="@+id/md_colorG"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_below="@+id/md_colorR"
-      android:layout_marginTop="@dimen/md_title_frame_margin_bottom"
-      android:layout_toEndOf="@+id/md_colorGLabel"
-      android:layout_toLeftOf="@+id/md_colorGValue"
-      android:layout_toRightOf="@+id/md_colorGLabel"
-      android:layout_toStartOf="@+id/md_colorGValue"
-      android:focusable="true"
-      android:max="255" />
-
-    <TextView
-      android:id="@+id/md_colorGValue"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorG"
-      android:layout_alignParentEnd="true"
-      android:layout_alignParentRight="true"
-      android:layout_alignTop="@+id/md_colorG"
-      android:layout_marginLeft="4dp"
-      android:layout_marginStart="4dp"
-      android:gravity="center"
-      android:minWidth="24dp"
-      android:text="0"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <!-- Blue -->
-
-    <TextView
-      android:id="@+id/md_colorBLabel"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorB"
-      android:layout_alignTop="@+id/md_colorB"
-      android:layout_marginEnd="4dp"
-      android:layout_marginRight="4dp"
-      android:text="B"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-    <SeekBar
-      android:id="@+id/md_colorB"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_below="@+id/md_colorG"
-      android:layout_marginTop="@dimen/md_title_frame_margin_bottom"
-      android:layout_toEndOf="@+id/md_colorBLabel"
-      android:layout_toLeftOf="@+id/md_colorBValue"
-      android:layout_toRightOf="@+id/md_colorBLabel"
-      android:layout_toStartOf="@+id/md_colorBValue"
-      android:max="255" />
-
-    <TextView
-      android:id="@+id/md_colorBValue"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:layout_alignBottom="@+id/md_colorB"
-      android:layout_alignParentEnd="true"
-      android:layout_alignParentRight="true"
-      android:layout_alignTop="@+id/md_colorB"
-      android:layout_marginLeft="4dp"
-      android:layout_marginStart="4dp"
-      android:gravity="center"
-      android:minWidth="24dp"
-      android:text="0"
-      android:textColor="?android:textColorPrimary"
-      android:textSize="@dimen/md_content_textsize"
-      tools:ignore="HardcodedText" />
-
-  </RelativeLayout>
-
-</LinearLayout>

+ 0 - 14
commons/src/main/res/layout/md_stub_colorchooser_grid.xml

@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.afollestad.materialdialogs.color.FillGridView xmlns:android="http://schemas.android.com/apk/res/android"
-  android:id="@+id/md_grid"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent"
-  android:clipToPadding="false"
-  android:columnWidth="@dimen/md_colorchooser_circlesize"
-  android:gravity="center"
-  android:horizontalSpacing="8dp"
-  android:numColumns="auto_fit"
-  android:orientation="vertical"
-  android:padding="16dp"
-  android:stretchMode="columnWidth"
-  android:verticalSpacing="8dp" />

+ 0 - 28
commons/src/main/res/layout/md_stub_inputpref.xml

@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  xmlns:tools="http://schemas.android.com/tools"
-  android:layout_width="match_parent"
-  android:layout_height="match_parent"
-  android:gravity="start"
-  android:orientation="vertical"
-  android:paddingBottom="@dimen/md_content_padding_bottom"
-  android:paddingLeft="@dimen/md_dialog_frame_margin"
-  android:paddingRight="@dimen/md_dialog_frame_margin"
-  android:paddingTop="@dimen/md_content_padding_top">
-
-  <TextView
-    android:id="@android:id/message"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center_horizontal"
-    android:layout_marginBottom="@dimen/md_content_padding_bottom"
-    android:layout_marginTop="4dp"
-    android:focusable="true"
-    android:fontFamily="sans-serif"
-    android:paddingLeft="2dp"
-    android:paddingRight="2dp"
-    android:textSize="@dimen/md_content_textsize"
-    tools:ignore="UnusedAttribute"
-    tools:text="Message" />
-
-</LinearLayout>

+ 0 - 6
commons/src/main/res/values-large/dimens.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-  <dimen name="md_preference_content_inset">28dp</dimen>
-
-</resources>

+ 0 - 8
commons/src/main/res/values/attrs.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-  <declare-styleable name="Preference">
-    <attr name="useStockLayout" format="boolean" />
-  </declare-styleable>
-
-</resources>

+ 0 - 12
commons/src/main/res/values/dimens.xml

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-  <dimen name="md_simpleitem_height">62dp</dimen>
-  <dimen name="md_simplelist_icon">40dp</dimen>
-  <dimen name="md_simplelist_icon_margin">16dp</dimen>
-  <dimen name="md_simplelist_textsize">18sp</dimen>
-
-  <dimen name="md_preference_content_inset">16dp</dimen>
-  <dimen name="md_colorchooser_circlesize">56dp</dimen>
-
-</resources>

+ 0 - 12
commons/src/main/res/values/strings.xml

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-  <string name="md_back_label">Back</string>
-  <string name="md_done_label">Done</string>
-  <string name="md_cancel_label">Cancel</string>
-  <string name="md_choose_label">Choose</string>
-  <string name="md_error_label">Error</string>
-  <string name="md_storage_perm_error">Your app has not been granted the READ_EXTERNAL_STORAGE permission.</string>
-  <string name="md_custom_label">Custom</string>
-  <string name="md_presets_label">Presets</string>
-  <string name="new_folder">New Folder</string>
-</resources>

+ 31 - 39
core/build.gradle

@@ -1,48 +1,40 @@
 apply plugin: 'com.android.library'
 apply plugin: 'kotlin-android'
-apply plugin: 'com.novoda.bintray-release'
-apply from: '../gradle/dependencies.gradle'
+apply from: '../dependencies.gradle'
+apply plugin: "com.github.ben-manes.versions"
+
+if (project.rootProject.file('local.properties').exists()) {
+  apply plugin: 'com.novoda.bintray-release'
+}
 
 android {
-    compileSdkVersion versions.compileSdk
-    buildToolsVersion versions.buildTools
-
-    defaultConfig {
-        minSdkVersion versions.minSdk
-        targetSdkVersion versions.compileSdk
-        versionCode versions.publishVersionCode
-        versionName versions.publishVersion
-        consumerProguardFiles 'progress-proguard.txt'
-    }
-    lintOptions {
-        abortOnError false
-        checkReleaseBuilds false
-    }
-    sourceSets {
-        main.res.srcDirs = [
-            'src/main/res',
-            'src/main/res-public'
-        ]
-    }
+  compileSdkVersion versions.compileSdk
+  buildToolsVersion versions.buildTools
+
+  defaultConfig {
+    minSdkVersion versions.minSdk
+    targetSdkVersion versions.compileSdk
+    versionCode versions.publishVersionCode
+    versionName versions.publishVersion
+  }
+
+  sourceSets {
+    main.res.srcDirs = [
+        'src/main/res',
+        'src/main/res-public'
+    ]
+  }
 }
 
 dependencies {
-    implementation 'com.google.code.findbugs:jsr305:' + versions.findBugs
-    implementation 'com.android.support:support-annotations:' + versions.supportLib
-    implementation 'com.android.support:appcompat-v7:' + versions.supportLib
-    implementation 'com.android.support:recyclerview-v7:' + versions.supportLib
-    implementation 'me.zhanghai.android.materialprogressbar:library:' + versions.mdProgressBar
-    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:' + versions.kotlin
-}
+  api 'com.android.support:support-annotations:' + versions.supportLib
+  api 'com.android.support:appcompat-v7:' + versions.supportLib
 
-publish {
-    userOrg = 'novoda'
-    groupId = 'com.afollestad.material-dialogs'
-    artifactId = 'core'
-    publishVersion = versions.publishVersion
-    website = 'https://github.com/afollestad/material-dialogs'
-    desc = 'A beautiful, fluid, and customizable dialogs API. '
-}
-repositories {
-    mavenCentral()
+  implementation 'com.android.support:recyclerview-v7:' + versions.supportLib
+  implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:' + versions.kotlin
 }
+
+apply from: '../spotless.gradle'
+
+ext.shard = 'core'
+apply from: '../bintrayconfig.gradle'

+ 3 - 3
core/src/main/AndroidManifest.xml

@@ -1,6 +1,6 @@
 <manifest xmlns:tools="http://schemas.android.com/tools"
-  package="com.afollestad.materialdialogs">
+    package="com.afollestad.materialdialogs">
 
-  <uses-sdk tools:overrideLibrary="me.zhanghai.android.materialprogressbar" />
-  <application />
+  <uses-sdk tools:overrideLibrary="me.zhanghai.android.materialprogressbar"/>
+  <application/>
 </manifest>

+ 0 - 227
core/src/main/java/com/afollestad/materialdialogs/DefaultRvAdapter.java

@@ -1,227 +0,0 @@
-package com.afollestad.materialdialogs;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.internal.MDTintHelper;
-import com.afollestad.materialdialogs.util.DialogUtils;
-
-/** @author Aidan Follestad (afollestad) */
-class DefaultRvAdapter extends RecyclerView.Adapter<DefaultRvAdapter.DefaultVH> {
-
-  private final MaterialDialog dialog;
-  @LayoutRes private final int layout;
-  private final GravityEnum itemGravity;
-  private InternalListCallback callback;
-
-  DefaultRvAdapter(MaterialDialog dialog, @LayoutRes int layout) {
-    this.dialog = dialog;
-    this.layout = layout;
-    this.itemGravity = dialog.builder.itemsGravity;
-  }
-
-  void setCallback(InternalListCallback callback) {
-    this.callback = callback;
-  }
-
-  @Override
-  public DefaultVH onCreateViewHolder(ViewGroup parent, int viewType) {
-    final View view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
-    DialogUtils.setBackgroundCompat(view, dialog.getListSelector());
-    return new DefaultVH(view, this);
-  }
-
-  @Override
-  public void onBindViewHolder(DefaultVH holder, int index) {
-    final View view = holder.itemView;
-    boolean disabled = DialogUtils.isIn(index, dialog.builder.disabledIndices);
-    int itemTextColor =
-        disabled
-            ? DialogUtils.adjustAlpha(dialog.builder.itemColor, 0.4f)
-            : dialog.builder.itemColor;
-    holder.itemView.setEnabled(!disabled);
-
-    switch (dialog.listType) {
-      case SINGLE:
-        {
-          @SuppressLint("CutPasteId")
-          RadioButton radio = (RadioButton) holder.control;
-          boolean selected = dialog.builder.selectedIndex == index;
-          if (dialog.builder.choiceWidgetColor != null) {
-            MDTintHelper.setTint(radio, dialog.builder.choiceWidgetColor);
-          } else {
-            MDTintHelper.setTint(radio, dialog.builder.widgetColor);
-          }
-          radio.setChecked(selected);
-          radio.setEnabled(!disabled);
-          break;
-        }
-      case MULTI:
-        {
-          @SuppressLint("CutPasteId")
-          CheckBox checkbox = (CheckBox) holder.control;
-          boolean selected = dialog.selectedIndicesList.contains(index);
-          if (dialog.builder.choiceWidgetColor != null) {
-            MDTintHelper.setTint(checkbox, dialog.builder.choiceWidgetColor);
-          } else {
-            MDTintHelper.setTint(checkbox, dialog.builder.widgetColor);
-          }
-          checkbox.setChecked(selected);
-          checkbox.setEnabled(!disabled);
-          break;
-        }
-    }
-
-    holder.title.setText(dialog.builder.items.get(index));
-    holder.title.setTextColor(itemTextColor);
-    dialog.setTypeface(holder.title, dialog.builder.regularFont);
-
-    setupGravity((ViewGroup) view);
-
-    if (dialog.builder.itemIds != null) {
-      if (index < dialog.builder.itemIds.length) {
-        view.setId(dialog.builder.itemIds[index]);
-      } else {
-        view.setId(-1);
-      }
-    }
-
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      ViewGroup group = (ViewGroup) view;
-      if (group.getChildCount() == 2) {
-        // Remove circular selector from check boxes and radio buttons on Lollipop
-        if (group.getChildAt(0) instanceof CompoundButton) {
-          group.getChildAt(0).setBackground(null);
-        } else if (group.getChildAt(1) instanceof CompoundButton) {
-          group.getChildAt(1).setBackground(null);
-        }
-      }
-    }
-  }
-
-  @Override
-  public int getItemCount() {
-    return dialog.builder.items != null ? dialog.builder.items.size() : 0;
-  }
-
-  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-  private void setupGravity(ViewGroup view) {
-    final LinearLayout itemRoot = (LinearLayout) view;
-    final int gravityInt = itemGravity.getGravityInt();
-    itemRoot.setGravity(gravityInt | Gravity.CENTER_VERTICAL);
-
-    if (view.getChildCount() == 2) {
-      if (itemGravity == GravityEnum.END
-          && !isRTL(view.getContext())
-          && view.getChildAt(0) instanceof CompoundButton) {
-        CompoundButton first = (CompoundButton) view.getChildAt(0);
-        view.removeView(first);
-
-        TextView second = (TextView) view.getChildAt(0);
-        view.removeView(second);
-        second.setPadding(
-            second.getPaddingRight(),
-            second.getPaddingTop(),
-            second.getPaddingLeft(),
-            second.getPaddingBottom());
-
-        view.addView(second);
-        view.addView(first);
-      } else if (itemGravity == GravityEnum.START
-          && isRTL(view.getContext())
-          && view.getChildAt(1) instanceof CompoundButton) {
-        CompoundButton first = (CompoundButton) view.getChildAt(1);
-        view.removeView(first);
-
-        TextView second = (TextView) view.getChildAt(0);
-        view.removeView(second);
-        second.setPadding(
-            second.getPaddingRight(),
-            second.getPaddingTop(),
-            second.getPaddingRight(),
-            second.getPaddingBottom());
-
-        view.addView(first);
-        view.addView(second);
-      }
-    }
-  }
-
-  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-  private boolean isRTL(Context context) {
-    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-      return false;
-    }
-    Configuration config = context.getResources().getConfiguration();
-    return config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
-  }
-
-  interface InternalListCallback {
-
-    boolean onItemSelected(
-        MaterialDialog dialog,
-        View itemView,
-        int position,
-        @Nullable CharSequence text,
-        boolean longPress);
-  }
-
-  static class DefaultVH extends RecyclerView.ViewHolder
-      implements View.OnClickListener, View.OnLongClickListener {
-
-    final CompoundButton control;
-    final TextView title;
-    final DefaultRvAdapter adapter;
-
-    DefaultVH(View itemView, DefaultRvAdapter adapter) {
-      super(itemView);
-      control = itemView.findViewById(R.id.md_control);
-      title = itemView.findViewById(R.id.md_title);
-      this.adapter = adapter;
-      itemView.setOnClickListener(this);
-      if (adapter.dialog.builder.listLongCallback != null) {
-        itemView.setOnLongClickListener(this);
-      }
-    }
-
-    @Override
-    public void onClick(View view) {
-      if (adapter.callback != null && getAdapterPosition() != RecyclerView.NO_POSITION) {
-        CharSequence text = null;
-        if (adapter.dialog.builder.items != null
-            && getAdapterPosition() < adapter.dialog.builder.items.size()) {
-          text = adapter.dialog.builder.items.get(getAdapterPosition());
-        }
-        adapter.callback.onItemSelected(adapter.dialog, view, getAdapterPosition(), text, false);
-      }
-    }
-
-    @Override
-    public boolean onLongClick(View view) {
-      if (adapter.callback != null && getAdapterPosition() != RecyclerView.NO_POSITION) {
-        CharSequence text = null;
-        if (adapter.dialog.builder.items != null
-            && getAdapterPosition() < adapter.dialog.builder.items.size()) {
-          text = adapter.dialog.builder.items.get(getAdapterPosition());
-        }
-        return adapter.callback.onItemSelected(
-            adapter.dialog, view, getAdapterPosition(), text, true);
-      }
-      return false;
-    }
-  }
-}

+ 0 - 8
core/src/main/java/com/afollestad/materialdialogs/DialogAction.java

@@ -1,8 +0,0 @@
-package com.afollestad.materialdialogs;
-
-/** @author Aidan Follestad (afollestad) */
-public enum DialogAction {
-  POSITIVE,
-  NEUTRAL,
-  NEGATIVE
-}

+ 0 - 67
core/src/main/java/com/afollestad/materialdialogs/DialogBase.java

@@ -1,67 +0,0 @@
-package com.afollestad.materialdialogs;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.support.annotation.Nullable;
-import android.view.View;
-import android.view.ViewGroup;
-import com.afollestad.materialdialogs.internal.MDRootLayout;
-
-/** @author Aidan Follestad (afollestad) */
-class DialogBase extends Dialog implements DialogInterface.OnShowListener {
-
-  protected MDRootLayout view;
-  private OnShowListener showListener;
-
-  DialogBase(Context context, int theme) {
-    super(context, theme);
-  }
-
-  @Override
-  public View findViewById(int id) {
-    return view.findViewById(id);
-  }
-
-  @Override
-  public final void setOnShowListener(@Nullable OnShowListener listener) {
-    showListener = listener;
-  }
-
-  final void setOnShowListenerInternal() {
-    super.setOnShowListener(this);
-  }
-
-  final void setViewInternal(View view) {
-    super.setContentView(view);
-  }
-
-  @Override
-  public void onShow(DialogInterface dialog) {
-    if (showListener != null) {
-      showListener.onShow(dialog);
-    }
-  }
-
-  @Override
-  @Deprecated
-  public void setContentView(int layoutResID) throws IllegalAccessError {
-    throw new IllegalAccessError(
-        "setContentView() is not supported in MaterialDialog. Specify a custom view in the Builder instead.");
-  }
-
-  @Override
-  @Deprecated
-  public void setContentView(View view) throws IllegalAccessError {
-    throw new IllegalAccessError(
-        "setContentView() is not supported in MaterialDialog. Specify a custom view in the Builder instead.");
-  }
-
-  @Override
-  @Deprecated
-  public void setContentView(View view, @Nullable ViewGroup.LayoutParams params)
-      throws IllegalAccessError {
-    throw new IllegalAccessError(
-        "setContentView() is not supported in MaterialDialog. Specify a custom view in the Builder instead.");
-  }
-}

+ 0 - 553
core/src/main/java/com/afollestad/materialdialogs/DialogInit.java

@@ -1,553 +0,0 @@
-package com.afollestad.materialdialogs;
-
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.os.Build;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.StyleRes;
-import android.support.annotation.UiThread;
-import android.text.InputType;
-import android.text.method.LinkMovementMethod;
-import android.text.method.PasswordTransformationMethod;
-import android.view.Display;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.ProgressBar;
-import android.widget.ScrollView;
-import com.afollestad.materialdialogs.internal.MDAdapter;
-import com.afollestad.materialdialogs.internal.MDButton;
-import com.afollestad.materialdialogs.internal.MDRootLayout;
-import com.afollestad.materialdialogs.internal.MDTintHelper;
-import com.afollestad.materialdialogs.util.DialogUtils;
-import java.util.ArrayList;
-import java.util.Arrays;
-import me.zhanghai.android.materialprogressbar.HorizontalProgressDrawable;
-import me.zhanghai.android.materialprogressbar.IndeterminateCircularProgressDrawable;
-import me.zhanghai.android.materialprogressbar.IndeterminateHorizontalProgressDrawable;
-
-/**
- * Used by MaterialDialog while initializing the dialog. Offloads some of the code to make the main
- * class cleaner and easier to read/maintain.
- *
- * @author Aidan Follestad (afollestad)
- */
-class DialogInit {
-
-  @StyleRes
-  static int getTheme(MaterialDialog.Builder builder) {
-    boolean darkTheme =
-        DialogUtils.resolveBoolean(
-            builder.context, R.attr.md_dark_theme, builder.theme == Theme.DARK);
-    builder.theme = darkTheme ? Theme.DARK : Theme.LIGHT;
-    return darkTheme ? R.style.MD_Dark : R.style.MD_Light;
-  }
-
-  @LayoutRes
-  static int getInflateLayout(MaterialDialog.Builder builder) {
-    if (builder.customView != null) {
-      return R.layout.md_dialog_custom;
-    } else if (builder.items != null || builder.adapter != null) {
-      if (builder.checkBoxPrompt != null) {
-        return R.layout.md_dialog_list_check;
-      }
-      return R.layout.md_dialog_list;
-    } else if (builder.progress > -2) {
-      return R.layout.md_dialog_progress;
-    } else if (builder.indeterminateProgress) {
-      if (builder.indeterminateIsHorizontalProgress) {
-        return R.layout.md_dialog_progress_indeterminate_horizontal;
-      }
-      return R.layout.md_dialog_progress_indeterminate;
-    } else if (builder.inputCallback != null) {
-      if (builder.checkBoxPrompt != null) {
-        return R.layout.md_dialog_input_check;
-      }
-      return R.layout.md_dialog_input;
-    } else if (builder.checkBoxPrompt != null) {
-      return R.layout.md_dialog_basic_check;
-    } else {
-      return R.layout.md_dialog_basic;
-    }
-  }
-
-  @SuppressWarnings("ConstantConditions")
-  @UiThread
-  static void init(final MaterialDialog dialog) {
-    final MaterialDialog.Builder builder = dialog.builder;
-
-    // Set cancelable flag and dialog background color
-    dialog.setCancelable(builder.cancelable);
-    dialog.setCanceledOnTouchOutside(builder.canceledOnTouchOutside);
-    if (builder.backgroundColor == 0) {
-      builder.backgroundColor =
-          DialogUtils.resolveColor(
-              dialog.getView().getContext(),
-              R.attr.md_background_color,
-              DialogUtils.resolveColor(dialog.getContext(), R.attr.colorBackgroundFloating));
-    }
-    if (builder.backgroundColor != 0) {
-      GradientDrawable drawable = new GradientDrawable();
-      drawable.setCornerRadius(
-          builder.context.getResources().getDimension(R.dimen.md_bg_corner_radius));
-      drawable.setColor(builder.backgroundColor);
-      dialog.getWindow().setBackgroundDrawable(drawable);
-    }
-
-    // Retrieve color theme attributes
-    if (!builder.positiveColorSet) {
-      builder.positiveColor =
-          DialogUtils.resolveActionTextColorStateList(
-              builder.context, R.attr.md_positive_color, builder.positiveColor);
-    }
-    if (!builder.neutralColorSet) {
-      builder.neutralColor =
-          DialogUtils.resolveActionTextColorStateList(
-              builder.context, R.attr.md_neutral_color, builder.neutralColor);
-    }
-    if (!builder.negativeColorSet) {
-      builder.negativeColor =
-          DialogUtils.resolveActionTextColorStateList(
-              builder.context, R.attr.md_negative_color, builder.negativeColor);
-    }
-    if (!builder.widgetColorSet) {
-      builder.widgetColor =
-          DialogUtils.resolveColor(builder.context, R.attr.md_widget_color, builder.widgetColor);
-    }
-
-    // Retrieve default title/content colors
-    if (!builder.titleColorSet) {
-      final int titleColorFallback =
-          DialogUtils.resolveColor(dialog.getContext(), android.R.attr.textColorPrimary);
-      builder.titleColor =
-          DialogUtils.resolveColor(builder.context, R.attr.md_title_color, titleColorFallback);
-    }
-    if (!builder.contentColorSet) {
-      final int contentColorFallback =
-          DialogUtils.resolveColor(dialog.getContext(), android.R.attr.textColorSecondary);
-      builder.contentColor =
-          DialogUtils.resolveColor(builder.context, R.attr.md_content_color, contentColorFallback);
-    }
-    if (!builder.itemColorSet) {
-      builder.itemColor =
-          DialogUtils.resolveColor(builder.context, R.attr.md_item_color, builder.contentColor);
-    }
-
-    // Retrieve references to views
-    dialog.title = dialog.view.findViewById(R.id.md_title);
-    dialog.icon = dialog.view.findViewById(R.id.md_icon);
-    dialog.titleFrame = dialog.view.findViewById(R.id.md_titleFrame);
-    dialog.content = dialog.view.findViewById(R.id.md_content);
-    dialog.recyclerView = dialog.view.findViewById(R.id.md_contentRecyclerView);
-    dialog.checkBoxPrompt = dialog.view.findViewById(R.id.md_promptCheckbox);
-
-    // Button views initially used by checkIfStackingNeeded()
-    dialog.positiveButton = dialog.view.findViewById(R.id.md_buttonDefaultPositive);
-    dialog.neutralButton = dialog.view.findViewById(R.id.md_buttonDefaultNeutral);
-    dialog.negativeButton = dialog.view.findViewById(R.id.md_buttonDefaultNegative);
-
-    // Don't allow the submit button to not be shown for input dialogs
-    if (builder.inputCallback != null && builder.positiveText == null) {
-      builder.positiveText = builder.context.getText(android.R.string.ok);
-    }
-
-    // Set up the initial visibility of action buttons based on whether or not text was set
-    dialog.positiveButton.setVisibility(builder.positiveText != null ? View.VISIBLE : View.GONE);
-    dialog.neutralButton.setVisibility(builder.neutralText != null ? View.VISIBLE : View.GONE);
-    dialog.negativeButton.setVisibility(builder.negativeText != null ? View.VISIBLE : View.GONE);
-
-    // Set up the focus of action buttons
-    dialog.positiveButton.setFocusable(true);
-    dialog.neutralButton.setFocusable(true);
-    dialog.negativeButton.setFocusable(true);
-    if (builder.positiveFocus) {
-      dialog.positiveButton.requestFocus();
-    }
-    if (builder.neutralFocus) {
-      dialog.neutralButton.requestFocus();
-    }
-    if (builder.negativeFocus) {
-      dialog.negativeButton.requestFocus();
-    }
-
-    // Setup icon
-    if (builder.icon != null) {
-      dialog.icon.setVisibility(View.VISIBLE);
-      dialog.icon.setImageDrawable(builder.icon);
-    } else {
-      Drawable d = DialogUtils.resolveDrawable(builder.context, R.attr.md_icon);
-      if (d != null) {
-        dialog.icon.setVisibility(View.VISIBLE);
-        dialog.icon.setImageDrawable(d);
-      } else {
-        dialog.icon.setVisibility(View.GONE);
-      }
-    }
-
-    // Setup icon size limiting
-    int maxIconSize = builder.maxIconSize;
-    if (maxIconSize == -1) {
-      maxIconSize = DialogUtils.resolveDimension(builder.context, R.attr.md_icon_max_size);
-    }
-    if (builder.limitIconToDefaultSize
-        || DialogUtils.resolveBoolean(builder.context, R.attr.md_icon_limit_icon_to_default_size)) {
-      maxIconSize = builder.context.getResources().getDimensionPixelSize(R.dimen.md_icon_max_size);
-    }
-    if (maxIconSize > -1) {
-      dialog.icon.setAdjustViewBounds(true);
-      dialog.icon.setMaxHeight(maxIconSize);
-      dialog.icon.setMaxWidth(maxIconSize);
-      dialog.icon.requestLayout();
-    }
-
-    // Setup divider color in case content scrolls
-    if (!builder.dividerColorSet) {
-      final int dividerFallback = DialogUtils.resolveColor(dialog.getContext(), R.attr.md_divider);
-      builder.dividerColor =
-          DialogUtils.resolveColor(builder.context, R.attr.md_divider_color, dividerFallback);
-    }
-    dialog.view.setDividerColor(builder.dividerColor);
-
-    // Setup title and title frame
-    if (dialog.title != null) {
-      dialog.setTypeface(dialog.title, builder.mediumFont);
-      dialog.title.setTextColor(builder.titleColor);
-      dialog.title.setGravity(builder.titleGravity.getGravityInt());
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-        //noinspection ResourceType
-        dialog.title.setTextAlignment(builder.titleGravity.getTextAlignment());
-      }
-
-      if (builder.title == null) {
-        dialog.titleFrame.setVisibility(View.GONE);
-      } else {
-        dialog.title.setText(builder.title);
-        dialog.titleFrame.setVisibility(View.VISIBLE);
-      }
-    }
-
-    // Setup content
-    if (dialog.content != null) {
-      dialog.content.setMovementMethod(new LinkMovementMethod());
-      dialog.setTypeface(dialog.content, builder.regularFont);
-      dialog.content.setLineSpacing(0f, builder.contentLineSpacingMultiplier);
-      if (builder.linkColor == null) {
-        dialog.content.setLinkTextColor(
-            DialogUtils.resolveColor(dialog.getContext(), android.R.attr.textColorPrimary));
-      } else {
-        dialog.content.setLinkTextColor(builder.linkColor);
-      }
-      dialog.content.setTextColor(builder.contentColor);
-      dialog.content.setGravity(builder.contentGravity.getGravityInt());
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-        //noinspection ResourceType
-        dialog.content.setTextAlignment(builder.contentGravity.getTextAlignment());
-      }
-
-      if (builder.content != null) {
-        dialog.content.setText(builder.content);
-        dialog.content.setVisibility(View.VISIBLE);
-      } else {
-        dialog.content.setVisibility(View.GONE);
-      }
-    }
-
-    // Setup prompt checkbox
-    if (dialog.checkBoxPrompt != null) {
-      dialog.checkBoxPrompt.setText(builder.checkBoxPrompt);
-      dialog.checkBoxPrompt.setChecked(builder.checkBoxPromptInitiallyChecked);
-      dialog.checkBoxPrompt.setOnCheckedChangeListener(builder.checkBoxPromptListener);
-      dialog.setTypeface(dialog.checkBoxPrompt, builder.regularFont);
-      dialog.checkBoxPrompt.setTextColor(builder.contentColor);
-      MDTintHelper.setTint(dialog.checkBoxPrompt, builder.widgetColor);
-    }
-
-    // Setup action buttons
-    dialog.view.setButtonGravity(builder.buttonsGravity);
-    dialog.view.setButtonStackedGravity(builder.btnStackedGravity);
-    dialog.view.setStackingBehavior(builder.stackingBehavior);
-    boolean textAllCaps;
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-      textAllCaps = DialogUtils.resolveBoolean(builder.context, android.R.attr.textAllCaps, true);
-      if (textAllCaps) {
-        textAllCaps = DialogUtils.resolveBoolean(builder.context, R.attr.textAllCaps, true);
-      }
-    } else {
-      textAllCaps = DialogUtils.resolveBoolean(builder.context, R.attr.textAllCaps, true);
-    }
-
-    MDButton positiveTextView = dialog.positiveButton;
-    dialog.setTypeface(positiveTextView, builder.mediumFont);
-    positiveTextView.setAllCapsCompat(textAllCaps);
-    positiveTextView.setText(builder.positiveText);
-    positiveTextView.setTextColor(builder.positiveColor);
-    dialog.positiveButton.setStackedSelector(dialog.getButtonSelector(DialogAction.POSITIVE, true));
-    dialog.positiveButton.setDefaultSelector(
-        dialog.getButtonSelector(DialogAction.POSITIVE, false));
-    dialog.positiveButton.setTag(DialogAction.POSITIVE);
-    dialog.positiveButton.setOnClickListener(dialog);
-
-    MDButton negativeTextView = dialog.negativeButton;
-    dialog.setTypeface(negativeTextView, builder.mediumFont);
-    negativeTextView.setAllCapsCompat(textAllCaps);
-    negativeTextView.setText(builder.negativeText);
-    negativeTextView.setTextColor(builder.negativeColor);
-    dialog.negativeButton.setStackedSelector(dialog.getButtonSelector(DialogAction.NEGATIVE, true));
-    dialog.negativeButton.setDefaultSelector(
-        dialog.getButtonSelector(DialogAction.NEGATIVE, false));
-    dialog.negativeButton.setTag(DialogAction.NEGATIVE);
-    dialog.negativeButton.setOnClickListener(dialog);
-
-    MDButton neutralTextView = dialog.neutralButton;
-    dialog.setTypeface(neutralTextView, builder.mediumFont);
-    neutralTextView.setAllCapsCompat(textAllCaps);
-    neutralTextView.setText(builder.neutralText);
-    neutralTextView.setTextColor(builder.neutralColor);
-    dialog.neutralButton.setStackedSelector(dialog.getButtonSelector(DialogAction.NEUTRAL, true));
-    dialog.neutralButton.setDefaultSelector(dialog.getButtonSelector(DialogAction.NEUTRAL, false));
-    dialog.neutralButton.setTag(DialogAction.NEUTRAL);
-    dialog.neutralButton.setOnClickListener(dialog);
-
-    // Setup list dialog stuff
-    if (builder.listCallbackMultiChoice != null) {
-      dialog.selectedIndicesList = new ArrayList<>();
-    }
-    if (dialog.recyclerView != null) {
-      if (builder.adapter == null) {
-        // Determine list type
-        if (builder.listCallbackSingleChoice != null) {
-          dialog.listType = MaterialDialog.ListType.SINGLE;
-        } else if (builder.listCallbackMultiChoice != null) {
-          dialog.listType = MaterialDialog.ListType.MULTI;
-          if (builder.selectedIndices != null) {
-            dialog.selectedIndicesList = new ArrayList<>(Arrays.asList(builder.selectedIndices));
-            builder.selectedIndices = null;
-          }
-        } else {
-          dialog.listType = MaterialDialog.ListType.REGULAR;
-        }
-        builder.adapter =
-            new DefaultRvAdapter(dialog, MaterialDialog.ListType.getLayoutForType(dialog.listType));
-      } else if (builder.adapter instanceof MDAdapter) {
-        // Notify simple list adapter of the dialog it belongs to
-        ((MDAdapter) builder.adapter).setDialog(dialog);
-      }
-    }
-
-    // Setup progress dialog stuff if needed
-    setupProgressDialog(dialog);
-
-    // Setup input dialog stuff if needed
-    setupInputDialog(dialog);
-
-    // Setup custom views
-    if (builder.customView != null) {
-      ((MDRootLayout) dialog.view.findViewById(R.id.md_root)).noTitleNoPadding();
-      FrameLayout frame = dialog.view.findViewById(R.id.md_customViewFrame);
-      dialog.customViewFrame = frame;
-      View innerView = builder.customView;
-      if (innerView.getParent() != null) {
-        ((ViewGroup) innerView.getParent()).removeView(innerView);
-      }
-      if (builder.wrapCustomViewInScroll) {
-        /* Apply the frame padding to the content, this allows the ScrollView to draw it's
-        over scroll glow without clipping */
-        final Resources r = dialog.getContext().getResources();
-        final int framePadding = r.getDimensionPixelSize(R.dimen.md_dialog_frame_margin);
-        final ScrollView sv = new ScrollView(dialog.getContext());
-        int paddingTop = r.getDimensionPixelSize(R.dimen.md_content_padding_top);
-        int paddingBottom = r.getDimensionPixelSize(R.dimen.md_content_padding_bottom);
-        sv.setClipToPadding(false);
-        if (innerView instanceof EditText) {
-          // Setting padding to an EditText causes visual errors, set it to the parent instead
-          sv.setPadding(framePadding, paddingTop, framePadding, paddingBottom);
-        } else {
-          // Setting padding to scroll view pushes the scroll bars out, don't do it if not necessary
-          // (like above)
-          sv.setPadding(0, paddingTop, 0, paddingBottom);
-          innerView.setPadding(framePadding, 0, framePadding, 0);
-        }
-        sv.addView(
-            innerView,
-            new ScrollView.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-        innerView = sv;
-      }
-      frame.addView(
-          innerView,
-          new ViewGroup.LayoutParams(
-              ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-    }
-
-    // Setup user listeners
-    if (builder.showListener != null) {
-      dialog.setOnShowListener(builder.showListener);
-    }
-    if (builder.cancelListener != null) {
-      dialog.setOnCancelListener(builder.cancelListener);
-    }
-    if (builder.dismissListener != null) {
-      dialog.setOnDismissListener(builder.dismissListener);
-    }
-    if (builder.keyListener != null) {
-      dialog.setOnKeyListener(builder.keyListener);
-    }
-
-    // Setup internal show listener
-    dialog.setOnShowListenerInternal();
-
-    // Other internal initialization
-    dialog.invalidateList();
-    dialog.setViewInternal(dialog.view);
-    dialog.checkIfListInitScroll();
-
-    // Min height and max width calculations
-    WindowManager wm = dialog.getWindow().getWindowManager();
-    Display display = wm.getDefaultDisplay();
-    Point size = new Point();
-    display.getSize(size);
-    final int windowWidth = size.x;
-    final int windowHeight = size.y;
-
-    final int windowVerticalPadding =
-        builder.context.getResources().getDimensionPixelSize(R.dimen.md_dialog_vertical_margin);
-    final int windowHorizontalPadding =
-        builder.context.getResources().getDimensionPixelSize(R.dimen.md_dialog_horizontal_margin);
-    final int maxWidth =
-        builder.context.getResources().getDimensionPixelSize(R.dimen.md_dialog_max_width);
-    final int calculatedWidth = windowWidth - (windowHorizontalPadding * 2);
-
-    dialog.view.setMaxHeight(windowHeight - windowVerticalPadding * 2);
-    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
-    lp.copyFrom(dialog.getWindow().getAttributes());
-    lp.width = Math.min(maxWidth, calculatedWidth);
-    dialog.getWindow().setAttributes(lp);
-  }
-
-  private static void fixCanvasScalingWhenHardwareAccelerated(ProgressBar pb) {
-    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
-      // Canvas scaling when hardware accelerated results in artifacts on older API levels, so
-      // we need to use software rendering
-      if (pb.isHardwareAccelerated() && pb.getLayerType() != View.LAYER_TYPE_SOFTWARE) {
-        pb.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-      }
-    }
-  }
-
-  private static void setupProgressDialog(final MaterialDialog dialog) {
-    final MaterialDialog.Builder builder = dialog.builder;
-    if (builder.indeterminateProgress || builder.progress > -2) {
-      dialog.progressBar = dialog.view.findViewById(android.R.id.progress);
-      if (dialog.progressBar == null) {
-        return;
-      }
-
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-        if (builder.indeterminateProgress) {
-          if (builder.indeterminateIsHorizontalProgress) {
-            IndeterminateHorizontalProgressDrawable d =
-                new IndeterminateHorizontalProgressDrawable(builder.getContext());
-            d.setTint(builder.widgetColor);
-            dialog.progressBar.setProgressDrawable(d);
-            dialog.progressBar.setIndeterminateDrawable(d);
-          } else {
-            IndeterminateCircularProgressDrawable d =
-                new IndeterminateCircularProgressDrawable(builder.getContext());
-            d.setTint(builder.widgetColor);
-            dialog.progressBar.setProgressDrawable(d);
-            dialog.progressBar.setIndeterminateDrawable(d);
-          }
-        } else {
-          HorizontalProgressDrawable d = new HorizontalProgressDrawable(builder.getContext());
-          d.setTint(builder.widgetColor);
-          dialog.progressBar.setProgressDrawable(d);
-          dialog.progressBar.setIndeterminateDrawable(d);
-        }
-      } else {
-        MDTintHelper.setTint(dialog.progressBar, builder.widgetColor);
-      }
-
-      if (!builder.indeterminateProgress || builder.indeterminateIsHorizontalProgress) {
-        dialog.progressBar.setIndeterminate(
-            builder.indeterminateProgress && builder.indeterminateIsHorizontalProgress);
-        dialog.progressBar.setProgress(0);
-        dialog.progressBar.setMax(builder.progressMax);
-        dialog.progressLabel = dialog.view.findViewById(R.id.md_label);
-        if (dialog.progressLabel != null) {
-          dialog.progressLabel.setTextColor(builder.contentColor);
-          dialog.setTypeface(dialog.progressLabel, builder.mediumFont);
-          dialog.progressLabel.setText(builder.progressPercentFormat.format(0));
-        }
-        dialog.progressMinMax = dialog.view.findViewById(R.id.md_minMax);
-        if (dialog.progressMinMax != null) {
-          dialog.progressMinMax.setTextColor(builder.contentColor);
-          dialog.setTypeface(dialog.progressMinMax, builder.regularFont);
-
-          if (builder.showMinMax) {
-            dialog.progressMinMax.setVisibility(View.VISIBLE);
-            dialog.progressMinMax.setText(
-                String.format(builder.progressNumberFormat, 0, builder.progressMax));
-            ViewGroup.MarginLayoutParams lp =
-                (ViewGroup.MarginLayoutParams) dialog.progressBar.getLayoutParams();
-            lp.leftMargin = 0;
-            lp.rightMargin = 0;
-          } else {
-            dialog.progressMinMax.setVisibility(View.GONE);
-          }
-        } else {
-          builder.showMinMax = false;
-        }
-      }
-    }
-
-    if (dialog.progressBar != null) {
-      fixCanvasScalingWhenHardwareAccelerated(dialog.progressBar);
-    }
-  }
-
-  private static void setupInputDialog(final MaterialDialog dialog) {
-    final MaterialDialog.Builder builder = dialog.builder;
-    dialog.input = dialog.view.findViewById(android.R.id.input);
-    if (dialog.input == null) {
-      return;
-    }
-    dialog.setTypeface(dialog.input, builder.regularFont);
-    if (builder.inputPrefill != null) {
-      dialog.input.setText(builder.inputPrefill);
-    }
-    dialog.setInternalInputCallback();
-    dialog.input.setHint(builder.inputHint);
-    dialog.input.setSingleLine();
-    dialog.input.setTextColor(builder.contentColor);
-    dialog.input.setHintTextColor(DialogUtils.adjustAlpha(builder.contentColor, 0.3f));
-    MDTintHelper.setTint(dialog.input, dialog.builder.widgetColor);
-
-    if (builder.inputType != -1) {
-      dialog.input.setInputType(builder.inputType);
-      if (builder.inputType != InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
-          && (builder.inputType & InputType.TYPE_TEXT_VARIATION_PASSWORD)
-              == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
-        // If the flags contain TYPE_TEXT_VARIATION_PASSWORD, apply the password transformation
-        // method automatically
-        dialog.input.setTransformationMethod(PasswordTransformationMethod.getInstance());
-      }
-    }
-
-    dialog.inputMinMax = dialog.view.findViewById(R.id.md_minMax);
-    if (builder.inputMinLength > 0 || builder.inputMaxLength > -1) {
-      dialog.invalidateInputMinMaxIndicator(
-          dialog.input.getText().toString().length(), !builder.inputAllowEmpty);
-    } else {
-      dialog.inputMinMax.setVisibility(View.GONE);
-      dialog.inputMinMax = null;
-    }
-
-    if (builder.inputFilters != null) {
-      dialog.input.setFilters(builder.inputFilters);
-    }
-  }
-}

+ 0 - 42
core/src/main/java/com/afollestad/materialdialogs/GravityEnum.java

@@ -1,42 +0,0 @@
-package com.afollestad.materialdialogs;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.view.Gravity;
-import android.view.View;
-
-public enum GravityEnum {
-  START,
-  CENTER,
-  END;
-
-  private static final boolean HAS_RTL =
-      Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
-
-  @SuppressLint("RtlHardcoded")
-  public int getGravityInt() {
-    switch (this) {
-      case START:
-        return HAS_RTL ? Gravity.START : Gravity.LEFT;
-      case CENTER:
-        return Gravity.CENTER_HORIZONTAL;
-      case END:
-        return HAS_RTL ? Gravity.END : Gravity.RIGHT;
-      default:
-        throw new IllegalStateException("Invalid gravity constant");
-    }
-  }
-
-  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-  public int getTextAlignment() {
-    switch (this) {
-      case CENTER:
-        return View.TEXT_ALIGNMENT_CENTER;
-      case END:
-        return View.TEXT_ALIGNMENT_VIEW_END;
-      default:
-        return View.TEXT_ALIGNMENT_VIEW_START;
-    }
-  }
-}

+ 0 - 2149
core/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java

@@ -1,2149 +0,0 @@
-package com.afollestad.materialdialogs;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.ColorStateList;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Handler;
-import android.support.annotation.ArrayRes;
-import android.support.annotation.AttrRes;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.annotation.DimenRes;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IntRange;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.Nullable;
-import android.support.annotation.StringRes;
-import android.support.annotation.UiThread;
-import android.support.v4.content.res.ResourcesCompat;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.text.Editable;
-import android.text.Html;
-import android.text.InputFilter;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.WindowManager;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-import android.widget.RadioButton;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.internal.MDButton;
-import com.afollestad.materialdialogs.internal.MDRootLayout;
-import com.afollestad.materialdialogs.internal.MDTintHelper;
-import com.afollestad.materialdialogs.internal.ThemeSingleton;
-import com.afollestad.materialdialogs.util.DialogUtils;
-import com.afollestad.materialdialogs.util.RippleHelper;
-import com.afollestad.materialdialogs.util.TypefaceHelper;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-/** @author Aidan Follestad (afollestad) */
-@SuppressWarnings({"WeakerAccess", "SameParameterValue", "unused"})
-public class MaterialDialog extends DialogBase
-    implements View.OnClickListener, DefaultRvAdapter.InternalListCallback {
-
-  protected final Builder builder;
-  private final Handler handler;
-  protected ImageView icon;
-  protected TextView title;
-  protected TextView content;
-
-  EditText input;
-  RecyclerView recyclerView;
-  View titleFrame;
-  FrameLayout customViewFrame;
-  ProgressBar progressBar;
-  TextView progressLabel;
-  TextView progressMinMax;
-  TextView inputMinMax;
-  CheckBox checkBoxPrompt;
-  MDButton positiveButton;
-  MDButton neutralButton;
-  MDButton negativeButton;
-  ListType listType;
-  List<Integer> selectedIndicesList;
-
-  @SuppressLint("InflateParams")
-  protected MaterialDialog(Builder builder) {
-    super(builder.context, DialogInit.getTheme(builder));
-    handler = new Handler();
-    this.builder = builder;
-    final LayoutInflater inflater = LayoutInflater.from(getContext());
-    view = (MDRootLayout) inflater.inflate(DialogInit.getInflateLayout(builder), null);
-    DialogInit.init(this);
-
-    // Don't keep a Context reference in the Builder after this point
-    builder.context = null;
-  }
-
-  public final Builder getBuilder() {
-    return builder;
-  }
-
-  public final void setTypeface(TextView target, @Nullable Typeface t) {
-    if (t == null) {
-      return;
-    }
-    int flags = target.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG;
-    target.setPaintFlags(flags);
-    target.setTypeface(t);
-  }
-
-  @Nullable
-  public Object getTag() {
-    return builder.tag;
-  }
-
-  final void checkIfListInitScroll() {
-    if (recyclerView == null) {
-      return;
-    }
-    recyclerView
-        .getViewTreeObserver()
-        .addOnGlobalLayoutListener(
-            new ViewTreeObserver.OnGlobalLayoutListener() {
-              @SuppressWarnings("ConstantConditions")
-              @Override
-              public void onGlobalLayout() {
-                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
-                  //noinspection deprecation
-                  recyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
-                } else {
-                  recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                }
-
-                if (listType == ListType.SINGLE || listType == ListType.MULTI) {
-                  int selectedIndex;
-                  if (listType == ListType.SINGLE) {
-                    if (builder.selectedIndex < 0) {
-                      return;
-                    }
-                    selectedIndex = builder.selectedIndex;
-                  } else {
-                    if (selectedIndicesList == null || selectedIndicesList.size() == 0) {
-                      return;
-                    }
-                    Collections.sort(selectedIndicesList);
-                    selectedIndex = selectedIndicesList.get(0);
-                  }
-
-                  final int fSelectedIndex = selectedIndex;
-                  recyclerView.post(
-                      new Runnable() {
-                        @Override
-                        public void run() {
-                          recyclerView.requestFocus();
-                          builder.layoutManager.scrollToPosition(fSelectedIndex);
-                        }
-                      });
-                }
-              }
-            });
-  }
-
-  /** Sets the dialog RecyclerView's adapter/layout manager, and it's item click listener. */
-  final void invalidateList() {
-    if (recyclerView == null) {
-      return;
-    } else if ((builder.items == null || builder.items.size() == 0) && builder.adapter == null) {
-      return;
-    }
-    if (builder.layoutManager == null) {
-      builder.layoutManager = new LinearLayoutManager(getContext());
-    }
-    if (recyclerView.getLayoutManager() == null) {
-      recyclerView.setLayoutManager(builder.layoutManager);
-    }
-    recyclerView.setAdapter(builder.adapter);
-    if (listType != null) {
-      ((DefaultRvAdapter) builder.adapter).setCallback(this);
-    }
-  }
-
-  @Override
-  public boolean onItemSelected(
-      MaterialDialog dialog, View view, int position, CharSequence text, boolean longPress) {
-    if (!view.isEnabled()) {
-      return false;
-    }
-    if (listType == null || listType == ListType.REGULAR) {
-      // Default adapter, non choice mode
-      if (builder.autoDismiss) {
-        // If auto dismiss is enabled, dismiss the dialog when a list item is selected
-        dismiss();
-      }
-      if (!longPress && builder.listCallback != null) {
-        builder.listCallback.onSelection(this, view, position, builder.items.get(position));
-      }
-      if (longPress && builder.listLongCallback != null) {
-        return builder.listLongCallback.onLongSelection(
-            this, view, position, builder.items.get(position));
-      }
-    } else {
-      // Default adapter, choice mode
-      if (listType == ListType.MULTI) {
-        final CheckBox cb = view.findViewById(R.id.md_control);
-        if (!cb.isEnabled()) {
-          return false;
-        }
-        final boolean shouldBeChecked = !selectedIndicesList.contains(position);
-        if (shouldBeChecked) {
-          // Add the selection to the states first so the callback includes it (when
-          // alwaysCallMultiChoiceCallback)
-          selectedIndicesList.add(position);
-          if (builder.alwaysCallMultiChoiceCallback) {
-            // If the checkbox wasn't previously selected, and the callback returns true, add it to
-            // the states and check it
-            if (sendMultiChoiceCallback()) {
-              cb.setChecked(true);
-            } else {
-              // The callback cancelled selection, remove it from the states
-              selectedIndicesList.remove(Integer.valueOf(position));
-            }
-          } else {
-            // The callback was not used to check if selection is allowed, just select it
-            cb.setChecked(true);
-          }
-        } else {
-          // Remove the selection from the states first so the callback does not include it (when
-          // alwaysCallMultiChoiceCallback)
-          selectedIndicesList.remove(Integer.valueOf(position));
-          if (builder.alwaysCallMultiChoiceCallback) {
-            // If the checkbox was previously selected, and the callback returns true, remove it
-            // from the states and uncheck it
-            if (sendMultiChoiceCallback()) {
-              cb.setChecked(false);
-            } else {
-              // The callback cancelled unselection, re-add it to the states
-              selectedIndicesList.add(position);
-            }
-          } else {
-            // The callback was not used to check if the unselection is allowed, just uncheck it
-            cb.setChecked(false);
-          }
-        }
-      } else if (listType == ListType.SINGLE) {
-        final RadioButton radio = view.findViewById(R.id.md_control);
-        if (!radio.isEnabled()) {
-          return false;
-        }
-        boolean allowSelection = true;
-        final int oldSelected = builder.selectedIndex;
-
-        if (builder.autoDismiss && builder.positiveText == null) {
-          // If auto dismiss is enabled, and no action button is visible to approve the selection,
-          // dismiss the dialog
-          dismiss();
-          // Don't allow the selection to be updated since the dialog is being dismissed anyways
-          allowSelection = false;
-          // Update selected index and send callback
-          builder.selectedIndex = position;
-          sendSingleChoiceCallback(view);
-        } else if (builder.alwaysCallSingleChoiceCallback) {
-          // Temporarily set the new index so the callback uses the right one
-          builder.selectedIndex = position;
-          // Only allow the radio button to be checked if the callback returns true
-          allowSelection = sendSingleChoiceCallback(view);
-          // Restore the old selected index, so the state is updated below
-          builder.selectedIndex = oldSelected;
-        }
-        // Update the checked states
-        if (allowSelection) {
-          builder.selectedIndex = position;
-          radio.setChecked(true);
-          builder.adapter.notifyItemChanged(oldSelected);
-          builder.adapter.notifyItemChanged(position);
-        }
-      }
-    }
-    return true;
-  }
-
-  final Drawable getListSelector() {
-    if (builder.listSelector != 0) {
-      return ResourcesCompat.getDrawable(getContext().getResources(), builder.listSelector, null);
-    }
-    final Drawable d = DialogUtils.resolveDrawable(getContext(), R.attr.md_list_selector);
-    if (d != null) {
-      return d;
-    }
-    return DialogUtils.resolveDrawable(getContext(), R.attr.md_list_selector);
-  }
-
-  public RecyclerView getRecyclerView() {
-    return recyclerView;
-  }
-
-  public boolean isPromptCheckBoxChecked() {
-    return checkBoxPrompt != null && checkBoxPrompt.isChecked();
-  }
-
-  public void setPromptCheckBoxChecked(boolean checked) {
-    if (checkBoxPrompt != null) {
-      checkBoxPrompt.setChecked(checked);
-    }
-  }
-
-  /* package */ Drawable getButtonSelector(DialogAction which, boolean isStacked) {
-    if (isStacked) {
-      if (builder.btnSelectorStacked != 0) {
-        return ResourcesCompat.getDrawable(
-            getContext().getResources(), builder.btnSelectorStacked, null);
-      }
-      final Drawable d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_stacked_selector);
-      if (d != null) {
-        return d;
-      }
-      return DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_stacked_selector);
-    } else {
-      switch (which) {
-        default:
-          {
-            if (builder.btnSelectorPositive != 0) {
-              return ResourcesCompat.getDrawable(
-                  getContext().getResources(), builder.btnSelectorPositive, null);
-            }
-            Drawable d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_positive_selector);
-            if (d != null) {
-              return d;
-            }
-            d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_positive_selector);
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-              RippleHelper.applyColor(d, builder.buttonRippleColor);
-            }
-            return d;
-          }
-        case NEUTRAL:
-          {
-            if (builder.btnSelectorNeutral != 0) {
-              return ResourcesCompat.getDrawable(
-                  getContext().getResources(), builder.btnSelectorNeutral, null);
-            }
-            Drawable d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_neutral_selector);
-            if (d != null) {
-              return d;
-            }
-            d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_neutral_selector);
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-              RippleHelper.applyColor(d, builder.buttonRippleColor);
-            }
-            return d;
-          }
-        case NEGATIVE:
-          {
-            if (builder.btnSelectorNegative != 0) {
-              return ResourcesCompat.getDrawable(
-                  getContext().getResources(), builder.btnSelectorNegative, null);
-            }
-            Drawable d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_negative_selector);
-            if (d != null) {
-              return d;
-            }
-            d = DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_negative_selector);
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-              RippleHelper.applyColor(d, builder.buttonRippleColor);
-            }
-            return d;
-          }
-      }
-    }
-  }
-
-  private boolean sendSingleChoiceCallback(View v) {
-    if (builder.listCallbackSingleChoice == null) {
-      return false;
-    }
-    CharSequence text = null;
-    if (builder.selectedIndex >= 0 && builder.selectedIndex < builder.items.size()) {
-      text = builder.items.get(builder.selectedIndex);
-    }
-    return builder.listCallbackSingleChoice.onSelection(this, v, builder.selectedIndex, text);
-  }
-
-  private boolean sendMultiChoiceCallback() {
-    if (builder.listCallbackMultiChoice == null) {
-      return false;
-    }
-    Collections.sort(selectedIndicesList); // make sure the indices are in order
-    List<CharSequence> selectedTitles = new ArrayList<>();
-    for (Integer i : selectedIndicesList) {
-      if (i < 0 || i > builder.items.size() - 1) {
-        continue;
-      }
-      selectedTitles.add(builder.items.get(i));
-    }
-    return builder.listCallbackMultiChoice.onSelection(
-        this,
-        selectedIndicesList.toArray(new Integer[selectedIndicesList.size()]),
-        selectedTitles.toArray(new CharSequence[selectedTitles.size()]));
-  }
-
-  @Override
-  public final void onClick(View v) {
-    DialogAction tag = (DialogAction) v.getTag();
-    switch (tag) {
-      case POSITIVE:
-        if (builder.onPositiveCallback != null) {
-          builder.onPositiveCallback.onClick(this, tag);
-        }
-        if (!builder.alwaysCallSingleChoiceCallback) {
-          sendSingleChoiceCallback(v);
-        }
-        if (!builder.alwaysCallMultiChoiceCallback) {
-          sendMultiChoiceCallback();
-        }
-        if (builder.inputCallback != null && input != null && !builder.alwaysCallInputCallback) {
-          builder.inputCallback.onInput(this, input.getText());
-        }
-        if (builder.autoDismiss) {
-          dismiss();
-        }
-        break;
-      case NEGATIVE:
-        if (builder.onNegativeCallback != null) {
-          builder.onNegativeCallback.onClick(this, tag);
-        }
-        if (builder.autoDismiss) {
-          cancel();
-        }
-        break;
-      case NEUTRAL:
-        if (builder.onNeutralCallback != null) {
-          builder.onNeutralCallback.onClick(this, tag);
-        }
-        if (builder.autoDismiss) {
-          dismiss();
-        }
-        break;
-    }
-    if (builder.onAnyCallback != null) {
-      builder.onAnyCallback.onClick(this, tag);
-    }
-  }
-
-  @Override
-  @UiThread
-  public void show() {
-    try {
-      super.show();
-    } catch (WindowManager.BadTokenException e) {
-      throw new DialogException(
-          "Bad window token, you cannot show a dialog "
-              + "before an Activity is created or after it's hidden.");
-    }
-  }
-
-  /**
-   * Retrieves the view of an action button, allowing you to modify properties such as whether or
-   * not it's enabled. Use {@link #setActionButton(DialogAction, int)} to change text, since the
-   * view returned here is not the view that displays text.
-   *
-   * @param which The action button of which to get the view for.
-   * @return The view from the dialog's layout representing this action button.
-   */
-  public final MDButton getActionButton(DialogAction which) {
-    switch (which) {
-      default:
-        return positiveButton;
-      case NEUTRAL:
-        return neutralButton;
-      case NEGATIVE:
-        return negativeButton;
-    }
-  }
-
-  /** Retrieves the view representing the dialog as a whole. Be careful with this. */
-  public final View getView() {
-    return view;
-  }
-
-  @Nullable
-  public final EditText getInputEditText() {
-    return input;
-  }
-
-  /**
-   * Retrieves the TextView that contains the dialog title. If you want to update the title, use
-   * #{@link #setTitle(CharSequence)} instead.
-   */
-  public final TextView getTitleView() {
-    return title;
-  }
-
-  /** Retrieves the ImageView that contains the dialog icon. */
-  public ImageView getIconView() {
-    return icon;
-  }
-
-  /**
-   * Retrieves the TextView that contains the dialog content. If you want to update the content
-   * (message), use #{@link #setContent(CharSequence)} instead.
-   */
-  @Nullable
-  public final TextView getContentView() {
-    return content;
-  }
-
-  /**
-   * Retrieves the custom view that was inflated or set to the MaterialDialog during building.
-   *
-   * @return The custom view that was passed into the Builder.
-   */
-  @Nullable
-  public final View getCustomView() {
-    return builder.customView;
-  }
-
-  /**
-   * Updates an action button's title, causing invalidation to check if the action buttons should be
-   * stacked. Setting an action button's text to null is a shortcut for hiding it, too.
-   *
-   * @param which The action button to update.
-   * @param title The new title of the action button.
-   */
-  @UiThread
-  public final void setActionButton(final DialogAction which, @Nullable final CharSequence title) {
-    switch (which) {
-      default:
-        builder.positiveText = title;
-        positiveButton.setText(title);
-        positiveButton.setVisibility(title == null ? View.GONE : View.VISIBLE);
-        break;
-      case NEUTRAL:
-        builder.neutralText = title;
-        neutralButton.setText(title);
-        neutralButton.setVisibility(title == null ? View.GONE : View.VISIBLE);
-        break;
-      case NEGATIVE:
-        builder.negativeText = title;
-        negativeButton.setText(title);
-        negativeButton.setVisibility(title == null ? View.GONE : View.VISIBLE);
-        break;
-    }
-  }
-
-  /**
-   * Updates an action button's title, causing invalidation to check if the action buttons should be
-   * stacked.
-   *
-   * @param which The action button to update.
-   * @param titleRes The string resource of the new title of the action button.
-   */
-  public final void setActionButton(DialogAction which, @StringRes int titleRes) {
-    setActionButton(which, getContext().getText(titleRes));
-  }
-
-  /**
-   * Gets whether or not the positive, neutral, or negative action button is visible.
-   *
-   * @return Whether or not 1 or more action buttons is visible.
-   */
-  public final boolean hasActionButtons() {
-    return numberOfActionButtons() > 0;
-  }
-
-  /**
-   * Gets the number of visible action buttons.
-   *
-   * @return 0 through 3, depending on how many should be or are visible.
-   */
-  @SuppressWarnings("WeakerAccess")
-  public final int numberOfActionButtons() {
-    int number = 0;
-    if (positiveButton.getVisibility() == View.VISIBLE) {
-      number++;
-    }
-    if (neutralButton.getVisibility() == View.VISIBLE) {
-      number++;
-    }
-    if (negativeButton.getVisibility() == View.VISIBLE) {
-      number++;
-    }
-    return number;
-  }
-
-  @UiThread
-  @Override
-  public final void setTitle(CharSequence newTitle) {
-    title.setText(newTitle);
-  }
-
-  @UiThread
-  @Override
-  public final void setTitle(@StringRes int newTitleRes) {
-    setTitle(getContext().getString(newTitleRes));
-  }
-
-  @UiThread
-  public final void setTitle(@StringRes int newTitleRes, @Nullable Object... formatArgs) {
-    setTitle(getContext().getString(newTitleRes, formatArgs));
-  }
-
-  @UiThread
-  public void setIcon(@DrawableRes final int resId) {
-    icon.setImageResource(resId);
-    icon.setVisibility(resId != 0 ? View.VISIBLE : View.GONE);
-  }
-
-  @UiThread
-  public void setIcon(@Nullable final Drawable d) {
-    icon.setImageDrawable(d);
-    icon.setVisibility(d != null ? View.VISIBLE : View.GONE);
-  }
-
-  @UiThread
-  public void setIconAttribute(@AttrRes int attrId) {
-    Drawable d = DialogUtils.resolveDrawable(getContext(), attrId);
-    setIcon(d);
-  }
-
-  @UiThread
-  public final void setContent(CharSequence newContent) {
-    content.setText(newContent);
-    content.setVisibility(TextUtils.isEmpty(newContent) ? View.GONE : View.VISIBLE);
-  }
-
-  @UiThread
-  public final void setContent(@StringRes int newContentRes) {
-    setContent(getContext().getString(newContentRes));
-  }
-
-  @UiThread
-  public final void setContent(@StringRes int newContentRes, @Nullable Object... formatArgs) {
-    setContent(getContext().getString(newContentRes, formatArgs));
-  }
-
-  @Nullable
-  public final ArrayList<CharSequence> getItems() {
-    return builder.items;
-  }
-
-  @UiThread
-  public final void setItems(@Nullable CharSequence... items) {
-    if (builder.adapter == null) {
-      throw new IllegalStateException(
-          "This MaterialDialog instance does not "
-              + "yet have an adapter set to it. You cannot use setItems().");
-    }
-    if (items != null) {
-      builder.items = new ArrayList<>(items.length);
-      Collections.addAll(builder.items, items);
-    } else {
-      builder.items = null;
-    }
-    if (!(builder.adapter instanceof DefaultRvAdapter)) {
-      throw new IllegalStateException(
-          "When using a custom adapter, setItems() "
-              + "cannot be used. Set items through the adapter instead.");
-    }
-    notifyItemsChanged();
-  }
-
-  @UiThread
-  public final void notifyItemInserted(@IntRange(from = 0, to = Integer.MAX_VALUE) int index) {
-    builder.adapter.notifyItemInserted(index);
-  }
-
-  @UiThread
-  public final void notifyItemChanged(@IntRange(from = 0, to = Integer.MAX_VALUE) int index) {
-    builder.adapter.notifyItemChanged(index);
-  }
-
-  @UiThread
-  public final void notifyItemsChanged() {
-    builder.adapter.notifyDataSetChanged();
-  }
-
-  public final int getCurrentProgress() {
-    if (progressBar == null) {
-      return -1;
-    }
-    return progressBar.getProgress();
-  }
-
-  public ProgressBar getProgressBar() {
-    return progressBar;
-  }
-
-  public final void incrementProgress(final int by) {
-    setProgress(getCurrentProgress() + by);
-  }
-
-  public final void setProgress(final int progress) {
-    if (builder.progress <= -2) {
-      Log.w(
-          "MaterialDialog",
-          "Calling setProgress(int) on an indeterminate progress dialog has no effect!");
-      return;
-    }
-    progressBar.setProgress(progress);
-    final String progressNumberFormat = builder.progressNumberFormat;
-    final NumberFormat progressPercentFormat = builder.progressPercentFormat;
-    handler.post(
-        new Runnable() {
-          @Override
-          public void run() {
-            if (progressLabel != null) {
-              progressLabel.setText(
-                  progressPercentFormat.format(
-                      (float) getCurrentProgress() / (float) getMaxProgress()));
-            }
-            if (progressMinMax != null) {
-              progressMinMax.setText(
-                  String.format(progressNumberFormat, getCurrentProgress(), getMaxProgress()));
-            }
-          }
-        });
-  }
-
-  public final boolean isIndeterminateProgress() {
-    return builder.indeterminateProgress;
-  }
-
-  public final int getMaxProgress() {
-    if (progressBar == null) {
-      return -1;
-    }
-    return progressBar.getMax();
-  }
-
-  public final void setMaxProgress(final int max) {
-    if (builder.progress <= -2) {
-      throw new IllegalStateException("Cannot use setMaxProgress() on this dialog.");
-    }
-    progressBar.setMax(max);
-  }
-
-  /**
-   * Change the format of the small text showing the percentage of progress. The default is
-   * NumberFormat.getPercentageInstance().
-   */
-  public final void setProgressPercentFormat(NumberFormat format) {
-    builder.progressPercentFormat = format;
-    setProgress(getCurrentProgress()); // invalidates display
-  }
-
-  /**
-   * Change the format of the small text showing current and maximum units of progress. The default
-   * is "%1d/%2d".
-   */
-  public final void setProgressNumberFormat(String format) {
-    builder.progressNumberFormat = format;
-    setProgress(getCurrentProgress()); // invalidates display
-  }
-
-  public final boolean isCancelled() {
-    return !isShowing();
-  }
-
-  /**
-   * Convenience method for getting the currently selected index of a single choice list.
-   *
-   * @return Currently selected index of a single choice list, or -1 if not showing a single choice
-   *     list
-   */
-  public int getSelectedIndex() {
-    if (builder.listCallbackSingleChoice != null) {
-      return builder.selectedIndex;
-    } else {
-      return -1;
-    }
-  }
-
-  /**
-   * Convenience method for setting the currently selected index of a single choice list. This only
-   * works if you are not using a custom adapter; if you're using a custom adapter, an
-   * IllegalStateException is thrown. Note that this does not call the respective single choice
-   * callback.
-   *
-   * @param index The index of the list item to check.
-   */
-  @UiThread
-  public void setSelectedIndex(int index) {
-    builder.selectedIndex = index;
-    if (builder.adapter != null && builder.adapter instanceof DefaultRvAdapter) {
-      builder.adapter.notifyDataSetChanged();
-    } else {
-      throw new IllegalStateException(
-          "You can only use setSelectedIndex() " + "with the default adapter implementation.");
-    }
-  }
-
-  /**
-   * Convenience method for getting the currently selected indices of a multi choice list
-   *
-   * @return Currently selected index of a multi choice list, or null if not showing a multi choice
-   *     list
-   */
-  @Nullable
-  public Integer[] getSelectedIndices() {
-    if (builder.listCallbackMultiChoice != null) {
-      return selectedIndicesList.toArray(new Integer[selectedIndicesList.size()]);
-    } else {
-      return null;
-    }
-  }
-
-  /**
-   * Convenience method for setting the currently selected indices of a multi choice list. This only
-   * works if you are not using a custom adapter; if you're using a custom adapter, an
-   * IllegalStateException is thrown. Note that this does not call the respective multi choice
-   * callback.
-   *
-   * @param indices The indices of the list items to check.
-   */
-  @UiThread
-  public void setSelectedIndices(Integer[] indices) {
-    selectedIndicesList = new ArrayList<>(Arrays.asList(indices));
-    if (builder.adapter != null && builder.adapter instanceof DefaultRvAdapter) {
-      builder.adapter.notifyDataSetChanged();
-    } else {
-      throw new IllegalStateException(
-          "You can only use setSelectedIndices() " + "with the default adapter implementation.");
-    }
-  }
-
-  /** Clears all selected checkboxes from multi choice list dialogs. */
-  public void clearSelectedIndices() {
-    clearSelectedIndices(true);
-  }
-
-  /**
-   * Clears all selected checkboxes from multi choice list dialogs.
-   *
-   * @param sendCallback Defaults to true. True will notify the multi-choice callback, if any.
-   */
-  public void clearSelectedIndices(boolean sendCallback) {
-    if (listType == null || listType != ListType.MULTI) {
-      throw new IllegalStateException(
-          "You can only use clearSelectedIndices() " + "with multi choice list dialogs.");
-    }
-    if (builder.adapter != null && builder.adapter instanceof DefaultRvAdapter) {
-      if (selectedIndicesList != null) {
-        selectedIndicesList.clear();
-      }
-      builder.adapter.notifyDataSetChanged();
-      if (sendCallback && builder.listCallbackMultiChoice != null) {
-        sendMultiChoiceCallback();
-      }
-    } else {
-      throw new IllegalStateException(
-          "You can only use clearSelectedIndices() " + "with the default adapter implementation.");
-    }
-  }
-
-  /** Selects all checkboxes in multi choice list dialogs. */
-  public void selectAllIndices() {
-    selectAllIndices(true);
-  }
-
-  /**
-   * Selects all checkboxes in multi choice list dialogs.
-   *
-   * @param sendCallback Defaults to true. True will notify the multi-choice callback, if any.
-   */
-  public void selectAllIndices(boolean sendCallback) {
-    if (listType == null || listType != ListType.MULTI) {
-      throw new IllegalStateException(
-          "You can only use selectAllIndices() with " + "multi choice list dialogs.");
-    }
-    if (builder.adapter != null && builder.adapter instanceof DefaultRvAdapter) {
-      if (selectedIndicesList == null) {
-        selectedIndicesList = new ArrayList<>();
-      }
-      for (int i = 0; i < builder.adapter.getItemCount(); i++) {
-        if (!selectedIndicesList.contains(i)) {
-          selectedIndicesList.add(i);
-        }
-      }
-      builder.adapter.notifyDataSetChanged();
-      if (sendCallback && builder.listCallbackMultiChoice != null) {
-        sendMultiChoiceCallback();
-      }
-    } else {
-      throw new IllegalStateException(
-          "You can only use selectAllIndices() with the " + "default adapter implementation.");
-    }
-  }
-
-  @Override
-  public final void onShow(DialogInterface dialog) {
-    if (input != null) {
-      DialogUtils.showKeyboard(this);
-      if (input.getText().length() > 0) {
-        input.setSelection(input.getText().length());
-      }
-    }
-    super.onShow(dialog);
-  }
-
-  void setInternalInputCallback() {
-    if (input == null) {
-      return;
-    }
-    input.addTextChangedListener(
-        new TextWatcher() {
-          @Override
-          public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
-          @Override
-          public void onTextChanged(CharSequence s, int start, int before, int count) {
-            final int length = s.toString().length();
-            boolean emptyDisabled = false;
-            if (!builder.inputAllowEmpty) {
-              emptyDisabled = length == 0;
-              final View positiveAb = getActionButton(DialogAction.POSITIVE);
-              positiveAb.setEnabled(!emptyDisabled);
-            }
-            invalidateInputMinMaxIndicator(length, emptyDisabled);
-            if (builder.alwaysCallInputCallback) {
-              builder.inputCallback.onInput(MaterialDialog.this, s);
-            }
-          }
-
-          @Override
-          public void afterTextChanged(Editable s) {}
-        });
-  }
-
-  void invalidateInputMinMaxIndicator(int currentLength, boolean emptyDisabled) {
-    if (inputMinMax != null) {
-      if (builder.inputMaxLength > 0) {
-        inputMinMax.setText(
-            String.format(Locale.getDefault(), "%d/%d", currentLength, builder.inputMaxLength));
-        inputMinMax.setVisibility(View.VISIBLE);
-      } else {
-        inputMinMax.setVisibility(View.GONE);
-      }
-      final boolean isDisabled =
-          (emptyDisabled && currentLength == 0)
-              || (builder.inputMaxLength > 0 && currentLength > builder.inputMaxLength)
-              || currentLength < builder.inputMinLength;
-      final int colorText = isDisabled ? builder.inputRangeErrorColor : builder.contentColor;
-      final int colorWidget = isDisabled ? builder.inputRangeErrorColor : builder.widgetColor;
-      if (builder.inputMaxLength > 0) {
-        inputMinMax.setTextColor(colorText);
-      }
-      MDTintHelper.setTint(input, colorWidget);
-      final View positiveAb = getActionButton(DialogAction.POSITIVE);
-      positiveAb.setEnabled(!isDisabled);
-    }
-  }
-
-  @Override
-  public void dismiss() {
-    if (input != null) {
-      DialogUtils.hideKeyboard(this);
-    }
-    super.dismiss();
-  }
-
-  enum ListType {
-    REGULAR,
-    SINGLE,
-    MULTI;
-
-    public static int getLayoutForType(ListType type) {
-      switch (type) {
-        case REGULAR:
-          return R.layout.md_listitem;
-        case SINGLE:
-          return R.layout.md_listitem_singlechoice;
-        case MULTI:
-          return R.layout.md_listitem_multichoice;
-        default:
-          throw new IllegalArgumentException("Not a valid list type");
-      }
-    }
-  }
-
-  /** A callback used for regular list dialogs. */
-  public interface ListCallback {
-    void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text);
-  }
-
-  /** A callback used for regular list dialogs. */
-  public interface ListLongCallback {
-    boolean onLongSelection(MaterialDialog dialog, View itemView, int position, CharSequence text);
-  }
-
-  /** A callback used for multi choice (check box) list dialogs. */
-  public interface ListCallbackSingleChoice {
-
-    /**
-     * Return true to allow the radio button to be checked, if the alwaysCallSingleChoice() option
-     * is used.
-     *
-     * @param dialog The dialog of which a list item was selected.
-     * @param which The index of the item that was selected.
-     * @param text The text of the item that was selected.
-     * @return True to allow the radio button to be selected.
-     */
-    boolean onSelection(
-        MaterialDialog dialog, View itemView, int which, @Nullable CharSequence text);
-  }
-
-  /** A callback used for multi choice (check box) list dialogs. */
-  public interface ListCallbackMultiChoice {
-
-    /**
-     * Return true to allow the check box to be checked, if the alwaysCallSingleChoice() option is
-     * used.
-     *
-     * @param dialog The dialog of which a list item was selected.
-     * @param which The indices of the items that were selected.
-     * @param text The text of the items that were selected.
-     * @return True to allow the checkbox to be selected.
-     */
-    boolean onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text);
-  }
-
-  /** An alternate way to define a single callback. */
-  public interface SingleButtonCallback {
-    void onClick(MaterialDialog dialog, DialogAction which);
-  }
-
-  public interface InputCallback {
-    void onInput(MaterialDialog dialog, CharSequence input);
-  }
-
-  private static class DialogException extends WindowManager.BadTokenException {
-    DialogException(@SuppressWarnings("SameParameterValue") String message) {
-      super(message);
-    }
-  }
-
-  /** The class used to construct a MaterialDialog. */
-  @SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "ConstantConditions"})
-  public static class Builder {
-
-    protected Context context;
-    protected CharSequence title;
-    protected GravityEnum titleGravity = GravityEnum.START;
-    protected GravityEnum contentGravity = GravityEnum.START;
-    protected GravityEnum btnStackedGravity = GravityEnum.END;
-    protected GravityEnum itemsGravity = GravityEnum.START;
-    protected GravityEnum buttonsGravity = GravityEnum.START;
-    protected int buttonRippleColor = 0;
-    protected int titleColor = -1;
-    protected int contentColor = -1;
-    protected CharSequence content;
-    protected ArrayList<CharSequence> items;
-    protected CharSequence positiveText;
-    protected CharSequence neutralText;
-    protected CharSequence negativeText;
-    protected boolean positiveFocus;
-    protected boolean neutralFocus;
-    protected boolean negativeFocus;
-    protected View customView;
-    protected int widgetColor;
-    protected ColorStateList choiceWidgetColor;
-    protected ColorStateList positiveColor;
-    protected ColorStateList negativeColor;
-    protected ColorStateList neutralColor;
-    protected ColorStateList linkColor;
-    protected SingleButtonCallback onPositiveCallback;
-    protected SingleButtonCallback onNegativeCallback;
-    protected SingleButtonCallback onNeutralCallback;
-    protected SingleButtonCallback onAnyCallback;
-    protected ListCallback listCallback;
-    protected ListLongCallback listLongCallback;
-    protected ListCallbackSingleChoice listCallbackSingleChoice;
-    protected ListCallbackMultiChoice listCallbackMultiChoice;
-    protected boolean alwaysCallMultiChoiceCallback = false;
-    protected boolean alwaysCallSingleChoiceCallback = false;
-    protected Theme theme = Theme.LIGHT;
-    protected boolean cancelable = true;
-    protected boolean canceledOnTouchOutside = true;
-    protected float contentLineSpacingMultiplier = 1.2f;
-    protected int selectedIndex = -1;
-    protected Integer[] selectedIndices = null;
-    protected Integer[] disabledIndices = null;
-    protected boolean autoDismiss = true;
-    protected Typeface regularFont;
-    protected Typeface mediumFont;
-    protected Drawable icon;
-    protected boolean limitIconToDefaultSize;
-    protected int maxIconSize = -1;
-    protected RecyclerView.Adapter<?> adapter;
-    protected RecyclerView.LayoutManager layoutManager;
-    protected OnDismissListener dismissListener;
-    protected OnCancelListener cancelListener;
-    protected OnKeyListener keyListener;
-    protected OnShowListener showListener;
-    protected StackingBehavior stackingBehavior;
-    protected boolean wrapCustomViewInScroll;
-    protected int dividerColor;
-    protected int backgroundColor;
-    protected int itemColor;
-    protected boolean indeterminateProgress;
-    protected boolean showMinMax;
-    protected int progress = -2;
-    protected int progressMax = 0;
-    protected CharSequence inputPrefill;
-    protected CharSequence inputHint;
-    protected InputCallback inputCallback;
-    protected boolean inputAllowEmpty;
-    protected int inputType = -1;
-    protected boolean alwaysCallInputCallback;
-    protected int inputMinLength = -1;
-    protected int inputMaxLength = -1;
-    protected int inputRangeErrorColor = 0;
-    protected int[] itemIds;
-    protected CharSequence checkBoxPrompt;
-    protected boolean checkBoxPromptInitiallyChecked;
-    protected CheckBox.OnCheckedChangeListener checkBoxPromptListener;
-    protected InputFilter[] inputFilters;
-
-    protected String progressNumberFormat;
-    protected NumberFormat progressPercentFormat;
-    protected boolean indeterminateIsHorizontalProgress;
-
-    protected boolean titleColorSet = false;
-    protected boolean contentColorSet = false;
-    protected boolean itemColorSet = false;
-    protected boolean positiveColorSet = false;
-    protected boolean neutralColorSet = false;
-    protected boolean negativeColorSet = false;
-    protected boolean widgetColorSet = false;
-    protected boolean dividerColorSet = false;
-
-    @DrawableRes protected int listSelector;
-    @DrawableRes protected int btnSelectorStacked;
-    @DrawableRes protected int btnSelectorPositive;
-    @DrawableRes protected int btnSelectorNeutral;
-    @DrawableRes protected int btnSelectorNegative;
-
-    protected Object tag;
-
-    public Builder(Context context) {
-      this.context = context;
-      final int materialBlue = DialogUtils.getColor(context, R.color.md_material_blue_600);
-
-      // Retrieve default accent colors, which are used on the action buttons and progress bars
-      this.widgetColor = DialogUtils.resolveColor(context, R.attr.colorAccent, materialBlue);
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-        this.widgetColor =
-            DialogUtils.resolveColor(context, android.R.attr.colorAccent, this.widgetColor);
-      }
-
-      this.positiveColor = DialogUtils.getActionTextStateList(context, this.widgetColor);
-      this.negativeColor = DialogUtils.getActionTextStateList(context, this.widgetColor);
-      this.neutralColor = DialogUtils.getActionTextStateList(context, this.widgetColor);
-      this.linkColor =
-          DialogUtils.getActionTextStateList(
-              context, DialogUtils.resolveColor(context, R.attr.md_link_color, this.widgetColor));
-
-      int fallback = 0;
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-        fallback = DialogUtils.resolveColor(context, android.R.attr.colorControlHighlight);
-      }
-      this.buttonRippleColor =
-          DialogUtils.resolveColor(
-              context,
-              R.attr.md_btn_ripple_color,
-              DialogUtils.resolveColor(context, R.attr.colorControlHighlight, fallback));
-
-      this.progressPercentFormat = NumberFormat.getPercentInstance();
-      this.progressNumberFormat = "%1d/%2d";
-
-      // Set the default theme based on the Activity theme's primary color darkness (more white or
-      // more black)
-      final int primaryTextColor =
-          DialogUtils.resolveColor(context, android.R.attr.textColorPrimary);
-      this.theme = DialogUtils.isColorDark(primaryTextColor) ? Theme.LIGHT : Theme.DARK;
-
-      // Load theme values from the ThemeSingleton if needed
-      checkSingleton();
-
-      // Retrieve gravity settings from global theme attributes if needed
-      this.titleGravity =
-          DialogUtils.resolveGravityEnum(context, R.attr.md_title_gravity, this.titleGravity);
-      this.contentGravity =
-          DialogUtils.resolveGravityEnum(context, R.attr.md_content_gravity, this.contentGravity);
-      this.btnStackedGravity =
-          DialogUtils.resolveGravityEnum(
-              context, R.attr.md_btnstacked_gravity, this.btnStackedGravity);
-      this.itemsGravity =
-          DialogUtils.resolveGravityEnum(context, R.attr.md_items_gravity, this.itemsGravity);
-      this.buttonsGravity =
-          DialogUtils.resolveGravityEnum(context, R.attr.md_buttons_gravity, this.buttonsGravity);
-
-      final String mediumFont = DialogUtils.resolveString(context, R.attr.md_medium_font);
-      final String regularFont = DialogUtils.resolveString(context, R.attr.md_regular_font);
-      try {
-        typeface(mediumFont, regularFont);
-      } catch (Throwable ignored) {
-      }
-
-      if (this.mediumFont == null) {
-        try {
-          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            this.mediumFont = Typeface.create("sans-serif-medium", Typeface.NORMAL);
-          } else {
-            this.mediumFont = Typeface.create("sans-serif", Typeface.BOLD);
-          }
-        } catch (Throwable ignored) {
-          this.mediumFont = Typeface.DEFAULT_BOLD;
-        }
-      }
-      if (this.regularFont == null) {
-        try {
-          this.regularFont = Typeface.create("sans-serif", Typeface.NORMAL);
-        } catch (Throwable ignored) {
-          this.regularFont = Typeface.SANS_SERIF;
-          if (this.regularFont == null) {
-            this.regularFont = Typeface.DEFAULT;
-          }
-        }
-      }
-    }
-
-    public final Context getContext() {
-      return context;
-    }
-
-    public final int getItemColor() {
-      return itemColor;
-    }
-
-    public final Typeface getRegularFont() {
-      return regularFont;
-    }
-
-    @SuppressWarnings("ConstantConditions")
-    private void checkSingleton() {
-      if (ThemeSingleton.get(false) == null) {
-        return;
-      }
-      ThemeSingleton s = ThemeSingleton.get();
-      if (s.darkTheme) {
-        this.theme = Theme.DARK;
-      }
-      if (s.titleColor != 0) {
-        this.titleColor = s.titleColor;
-      }
-      if (s.contentColor != 0) {
-        this.contentColor = s.contentColor;
-      }
-      if (s.positiveColor != null) {
-        this.positiveColor = s.positiveColor;
-      }
-      if (s.neutralColor != null) {
-        this.neutralColor = s.neutralColor;
-      }
-      if (s.negativeColor != null) {
-        this.negativeColor = s.negativeColor;
-      }
-      if (s.itemColor != 0) {
-        this.itemColor = s.itemColor;
-      }
-      if (s.icon != null) {
-        this.icon = s.icon;
-      }
-      if (s.backgroundColor != 0) {
-        this.backgroundColor = s.backgroundColor;
-      }
-      if (s.dividerColor != 0) {
-        this.dividerColor = s.dividerColor;
-      }
-      if (s.btnSelectorStacked != 0) {
-        this.btnSelectorStacked = s.btnSelectorStacked;
-      }
-      if (s.listSelector != 0) {
-        this.listSelector = s.listSelector;
-      }
-      if (s.btnSelectorPositive != 0) {
-        this.btnSelectorPositive = s.btnSelectorPositive;
-      }
-      if (s.btnSelectorNeutral != 0) {
-        this.btnSelectorNeutral = s.btnSelectorNeutral;
-      }
-      if (s.btnSelectorNegative != 0) {
-        this.btnSelectorNegative = s.btnSelectorNegative;
-      }
-      if (s.widgetColor != 0) {
-        this.widgetColor = s.widgetColor;
-      }
-      if (s.linkColor != null) {
-        this.linkColor = s.linkColor;
-      }
-      this.titleGravity = s.titleGravity;
-      this.contentGravity = s.contentGravity;
-      this.btnStackedGravity = s.btnStackedGravity;
-      this.itemsGravity = s.itemsGravity;
-      this.buttonsGravity = s.buttonsGravity;
-    }
-
-    public Builder title(@StringRes int titleRes) {
-      title(this.context.getText(titleRes));
-      return this;
-    }
-
-    public Builder title(CharSequence title) {
-      this.title = title;
-      return this;
-    }
-
-    public Builder titleGravity(GravityEnum gravity) {
-      this.titleGravity = gravity;
-      return this;
-    }
-
-    public Builder buttonRippleColor(@ColorInt int color) {
-      this.buttonRippleColor = color;
-      return this;
-    }
-
-    public Builder buttonRippleColorRes(@ColorRes int colorRes) {
-      return buttonRippleColor(DialogUtils.getColor(this.context, colorRes));
-    }
-
-    public Builder buttonRippleColorAttr(@AttrRes int colorAttr) {
-      return buttonRippleColor(DialogUtils.resolveColor(this.context, colorAttr));
-    }
-
-    public Builder titleColor(@ColorInt int color) {
-      this.titleColor = color;
-      this.titleColorSet = true;
-      return this;
-    }
-
-    public Builder titleColorRes(@ColorRes int colorRes) {
-      return titleColor(DialogUtils.getColor(this.context, colorRes));
-    }
-
-    public Builder titleColorAttr(@AttrRes int colorAttr) {
-      return titleColor(DialogUtils.resolveColor(this.context, colorAttr));
-    }
-
-    /**
-     * Sets the fonts used in the dialog. It's recommended that you use {@link #typeface(String,
-     * String)} instead, to avoid duplicate Typeface allocations and high memory usage.
-     *
-     * @param medium The font used on titles and action buttons. Null uses device default.
-     * @param regular The font used everywhere else, like on the content and list items. Null uses
-     *     device default.
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder typeface(@Nullable Typeface medium, @Nullable Typeface regular) {
-      this.mediumFont = medium;
-      this.regularFont = regular;
-      return this;
-    }
-
-    /**
-     * Sets the fonts used in the dialog, by file names. This also uses TypefaceHelper in order to
-     * avoid any un-needed allocations (it recycles typefaces for you).
-     *
-     * @param medium The name of font in assets/fonts used on titles and action buttons (null uses
-     *     device default). E.g. [your-project]/app/main/assets/fonts/[medium]
-     * @param regular The name of font in assets/fonts used everywhere else, like content and list
-     *     items (null uses device default). E.g. [your-project]/app/main/assets/fonts/[regular]
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder typeface(@Nullable String medium, @Nullable String regular) {
-      if (medium != null && !medium.trim().isEmpty()) {
-        this.mediumFont = TypefaceHelper.get(this.context, medium);
-        if (this.mediumFont == null) {
-          throw new IllegalArgumentException("No font asset found for \"" + medium + "\"");
-        }
-      }
-      if (regular != null && !regular.trim().isEmpty()) {
-        this.regularFont = TypefaceHelper.get(this.context, regular);
-        if (this.regularFont == null) {
-          throw new IllegalArgumentException("No font asset found for \"" + regular + "\"");
-        }
-      }
-      return this;
-    }
-
-    public Builder icon(Drawable icon) {
-      this.icon = icon;
-      return this;
-    }
-
-    public Builder iconRes(@DrawableRes int icon) {
-      this.icon = ResourcesCompat.getDrawable(context.getResources(), icon, null);
-      return this;
-    }
-
-    public Builder iconAttr(@AttrRes int iconAttr) {
-      this.icon = DialogUtils.resolveDrawable(context, iconAttr);
-      return this;
-    }
-
-    public Builder content(@StringRes int contentRes) {
-      return content(contentRes, false);
-    }
-
-    public Builder content(@StringRes int contentRes, boolean html) {
-      CharSequence text = this.context.getText(contentRes);
-      if (html) {
-        text = Html.fromHtml(text.toString().replace("\n", "<br/>"));
-      }
-      return content(text);
-    }
-
-    public Builder content(CharSequence content) {
-      if (this.customView != null) {
-        throw new IllegalStateException(
-            "You cannot set content() " + "when you're using a custom view.");
-      }
-      this.content = content;
-      return this;
-    }
-
-    public Builder content(@StringRes int contentRes, Object... formatArgs) {
-      String str =
-          String.format(this.context.getString(contentRes), formatArgs).replace("\n", "<br/>");
-      //noinspection deprecation
-      return content(Html.fromHtml(str));
-    }
-
-    public Builder contentColor(@ColorInt int color) {
-      this.contentColor = color;
-      this.contentColorSet = true;
-      return this;
-    }
-
-    public Builder contentColorRes(@ColorRes int colorRes) {
-      contentColor(DialogUtils.getColor(this.context, colorRes));
-      return this;
-    }
-
-    public Builder contentColorAttr(@AttrRes int colorAttr) {
-      contentColor(DialogUtils.resolveColor(this.context, colorAttr));
-      return this;
-    }
-
-    public Builder contentGravity(GravityEnum gravity) {
-      this.contentGravity = gravity;
-      return this;
-    }
-
-    public Builder contentLineSpacing(float multiplier) {
-      this.contentLineSpacingMultiplier = multiplier;
-      return this;
-    }
-
-    public Builder items(Collection collection) {
-      if (collection.size() > 0) {
-        final CharSequence[] array = new CharSequence[collection.size()];
-        int i = 0;
-        for (Object obj : collection) {
-          array[i] = obj.toString();
-          i++;
-        }
-        items(array);
-      } else if (collection.size() == 0) {
-        items = new ArrayList<>();
-      }
-      return this;
-    }
-
-    public Builder items(@ArrayRes int itemsRes) {
-      items(this.context.getResources().getTextArray(itemsRes));
-      return this;
-    }
-
-    public Builder items(CharSequence... items) {
-      if (this.customView != null) {
-        throw new IllegalStateException(
-            "You cannot set items()" + " when you're using a custom view.");
-      }
-      this.items = new ArrayList<>();
-      Collections.addAll(this.items, items);
-      return this;
-    }
-
-    public Builder itemsCallback(ListCallback callback) {
-      this.listCallback = callback;
-      this.listCallbackSingleChoice = null;
-      this.listCallbackMultiChoice = null;
-      return this;
-    }
-
-    public Builder itemsLongCallback(ListLongCallback callback) {
-      this.listLongCallback = callback;
-      this.listCallbackSingleChoice = null;
-      this.listCallbackMultiChoice = null;
-      return this;
-    }
-
-    public Builder itemsColor(@ColorInt int color) {
-      this.itemColor = color;
-      this.itemColorSet = true;
-      return this;
-    }
-
-    public Builder itemsColorRes(@ColorRes int colorRes) {
-      return itemsColor(DialogUtils.getColor(this.context, colorRes));
-    }
-
-    public Builder itemsColorAttr(@AttrRes int colorAttr) {
-      return itemsColor(DialogUtils.resolveColor(this.context, colorAttr));
-    }
-
-    public Builder itemsGravity(GravityEnum gravity) {
-      this.itemsGravity = gravity;
-      return this;
-    }
-
-    public Builder itemsIds(int[] idsArray) {
-      this.itemIds = idsArray;
-      return this;
-    }
-
-    public Builder itemsIds(@ArrayRes int idsArrayRes) {
-      return itemsIds(context.getResources().getIntArray(idsArrayRes));
-    }
-
-    public Builder buttonsGravity(GravityEnum gravity) {
-      this.buttonsGravity = gravity;
-      return this;
-    }
-
-    /**
-     * Pass anything below 0 (such as -1) for the selected index to leave all options unselected
-     * initially. Otherwise pass the index of an item that will be selected initially.
-     *
-     * @param selectedIndex The checkbox index that will be selected initially.
-     * @param callback The callback that will be called when the presses the positive button.
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder itemsCallbackSingleChoice(int selectedIndex, ListCallbackSingleChoice callback) {
-      this.selectedIndex = selectedIndex;
-      this.listCallback = null;
-      this.listCallbackSingleChoice = callback;
-      this.listCallbackMultiChoice = null;
-      return this;
-    }
-
-    /**
-     * By default, the single choice callback is only called when the user clicks the positive
-     * button or if there are no buttons. Call this to force it to always call on item clicks even
-     * if the positive button exists.
-     *
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder alwaysCallSingleChoiceCallback() {
-      this.alwaysCallSingleChoiceCallback = true;
-      return this;
-    }
-
-    /**
-     * Pass null for the selected indices to leave all options unselected initially. Otherwise pass
-     * an array of indices that will be selected initially.
-     *
-     * @param selectedIndices The radio button indices that will be selected initially.
-     * @param callback The callback that will be called when the presses the positive button.
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder itemsCallbackMultiChoice(
-        @Nullable Integer[] selectedIndices, ListCallbackMultiChoice callback) {
-      this.selectedIndices = selectedIndices;
-      this.listCallback = null;
-      this.listCallbackSingleChoice = null;
-      this.listCallbackMultiChoice = callback;
-      return this;
-    }
-
-    /**
-     * Sets indices of items that are not clickable. If they are checkboxes or radio buttons, they
-     * will not be toggleable.
-     *
-     * @param disabledIndices The item indices that will be disabled from selection.
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder itemsDisabledIndices(@Nullable Integer... disabledIndices) {
-      this.disabledIndices = disabledIndices;
-      return this;
-    }
-
-    /**
-     * By default, the multi choice callback is only called when the user clicks the positive button
-     * or if there are no buttons. Call this to force it to always call on item clicks even if the
-     * positive button exists.
-     *
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder alwaysCallMultiChoiceCallback() {
-      this.alwaysCallMultiChoiceCallback = true;
-      return this;
-    }
-
-    public Builder positiveText(@StringRes int positiveRes) {
-      if (positiveRes == 0) {
-        return this;
-      }
-      positiveText(this.context.getText(positiveRes));
-      return this;
-    }
-
-    public Builder positiveText(CharSequence message) {
-      this.positiveText = message;
-      return this;
-    }
-
-    public Builder positiveColor(@ColorInt int color) {
-      return positiveColor(DialogUtils.getActionTextStateList(context, color));
-    }
-
-    public Builder positiveColorRes(@ColorRes int colorRes) {
-      return positiveColor(DialogUtils.getActionTextColorStateList(this.context, colorRes));
-    }
-
-    public Builder positiveColorAttr(@AttrRes int colorAttr) {
-      return positiveColor(
-          DialogUtils.resolveActionTextColorStateList(this.context, colorAttr, null));
-    }
-
-    public Builder positiveColor(ColorStateList colorStateList) {
-      this.positiveColor = colorStateList;
-      this.positiveColorSet = true;
-      return this;
-    }
-
-    public Builder positiveFocus(boolean isFocusedDefault) {
-      this.positiveFocus = isFocusedDefault;
-      return this;
-    }
-
-    public Builder neutralText(@StringRes int neutralRes) {
-      if (neutralRes == 0) {
-        return this;
-      }
-      return neutralText(this.context.getText(neutralRes));
-    }
-
-    public Builder neutralText(CharSequence message) {
-      this.neutralText = message;
-      return this;
-    }
-
-    public Builder negativeColor(@ColorInt int color) {
-      return negativeColor(DialogUtils.getActionTextStateList(context, color));
-    }
-
-    public Builder negativeColorRes(@ColorRes int colorRes) {
-      return negativeColor(DialogUtils.getActionTextColorStateList(this.context, colorRes));
-    }
-
-    public Builder negativeColorAttr(@AttrRes int colorAttr) {
-      return negativeColor(
-          DialogUtils.resolveActionTextColorStateList(this.context, colorAttr, null));
-    }
-
-    public Builder negativeColor(ColorStateList colorStateList) {
-      this.negativeColor = colorStateList;
-      this.negativeColorSet = true;
-      return this;
-    }
-
-    public Builder negativeText(@StringRes int negativeRes) {
-      if (negativeRes == 0) {
-        return this;
-      }
-      return negativeText(this.context.getText(negativeRes));
-    }
-
-    public Builder negativeText(CharSequence message) {
-      this.negativeText = message;
-      return this;
-    }
-
-    public Builder negativeFocus(boolean isFocusedDefault) {
-      this.negativeFocus = isFocusedDefault;
-      return this;
-    }
-
-    public Builder neutralColor(@ColorInt int color) {
-      return neutralColor(DialogUtils.getActionTextStateList(context, color));
-    }
-
-    public Builder neutralColorRes(@ColorRes int colorRes) {
-      return neutralColor(DialogUtils.getActionTextColorStateList(this.context, colorRes));
-    }
-
-    public Builder neutralColorAttr(@AttrRes int colorAttr) {
-      return neutralColor(
-          DialogUtils.resolveActionTextColorStateList(this.context, colorAttr, null));
-    }
-
-    public Builder neutralColor(ColorStateList colorStateList) {
-      this.neutralColor = colorStateList;
-      this.neutralColorSet = true;
-      return this;
-    }
-
-    public Builder neutralFocus(boolean isFocusedDefault) {
-      this.neutralFocus = isFocusedDefault;
-      return this;
-    }
-
-    public Builder linkColor(@ColorInt int color) {
-      return linkColor(DialogUtils.getActionTextStateList(context, color));
-    }
-
-    public Builder linkColorRes(@ColorRes int colorRes) {
-      return linkColor(DialogUtils.getActionTextColorStateList(this.context, colorRes));
-    }
-
-    public Builder linkColorAttr(@AttrRes int colorAttr) {
-      return linkColor(DialogUtils.resolveActionTextColorStateList(this.context, colorAttr, null));
-    }
-
-    public Builder linkColor(ColorStateList colorStateList) {
-      this.linkColor = colorStateList;
-      return this;
-    }
-
-    public Builder listSelector(@DrawableRes int selectorRes) {
-      this.listSelector = selectorRes;
-      return this;
-    }
-
-    public Builder btnSelectorStacked(@DrawableRes int selectorRes) {
-      this.btnSelectorStacked = selectorRes;
-      return this;
-    }
-
-    public Builder btnSelector(@DrawableRes int selectorRes) {
-      this.btnSelectorPositive = selectorRes;
-      this.btnSelectorNeutral = selectorRes;
-      this.btnSelectorNegative = selectorRes;
-      return this;
-    }
-
-    public Builder btnSelector(@DrawableRes int selectorRes, DialogAction which) {
-      switch (which) {
-        default:
-          this.btnSelectorPositive = selectorRes;
-          break;
-        case NEUTRAL:
-          this.btnSelectorNeutral = selectorRes;
-          break;
-        case NEGATIVE:
-          this.btnSelectorNegative = selectorRes;
-          break;
-      }
-      return this;
-    }
-
-    /**
-     * Sets the gravity used for the text in stacked action buttons. By default, it's #{@link
-     * GravityEnum#END}.
-     *
-     * @param gravity The gravity to use.
-     * @return The Builder instance so calls can be chained.
-     */
-    public Builder btnStackedGravity(GravityEnum gravity) {
-      this.btnStackedGravity = gravity;
-      return this;
-    }
-
-    public Builder checkBoxPrompt(
-        CharSequence prompt,
-        boolean initiallyChecked,
-        @Nullable CheckBox.OnCheckedChangeListener checkListener) {
-      this.checkBoxPrompt = prompt;
-      this.checkBoxPromptInitiallyChecked = initiallyChecked;
-      this.checkBoxPromptListener = checkListener;
-      return this;
-    }
-
-    public Builder checkBoxPromptRes(
-        @StringRes int prompt,
-        boolean initiallyChecked,
-        @Nullable CheckBox.OnCheckedChangeListener checkListener) {
-      return checkBoxPrompt(
-          context.getResources().getText(prompt), initiallyChecked, checkListener);
-    }
-
-    public Builder customView(@LayoutRes int layoutRes, boolean wrapInScrollView) {
-      LayoutInflater li = LayoutInflater.from(this.context);
-      return customView(li.inflate(layoutRes, null), wrapInScrollView);
-    }
-
-    public Builder customView(View view, boolean wrapInScrollView) {
-      if (this.content != null) {
-        throw new IllegalStateException("You cannot use customView() when you have content set.");
-      } else if (this.items != null) {
-        throw new IllegalStateException("You cannot use customView() when you have items set.");
-      } else if (this.inputCallback != null) {
-        throw new IllegalStateException("You cannot use customView() with an input dialog");
-      } else if (this.progress > -2 || this.indeterminateProgress) {
-        throw new IllegalStateException("You cannot use customView() with a progress dialog");
-      }
-      if (view.getParent() != null && view.getParent() instanceof ViewGroup) {
-        ((ViewGroup) view.getParent()).removeView(view);
-      }
-      this.customView = view;
-      this.wrapCustomViewInScroll = wrapInScrollView;
-      return this;
-    }
-
-    /**
-     * Makes this dialog a progress dialog.
-     *
-     * @param indeterminate If true, an infinite circular spinner is shown. If false, a horizontal
-     *     progress bar is shown that is incremented or set via the built MaterialDialog instance.
-     * @param max When indeterminate is false, the max value the horizontal progress bar can get to.
-     * @return An instance of the Builder so calls can be chained.
-     */
-    public Builder progress(boolean indeterminate, int max) {
-      if (this.customView != null) {
-        throw new IllegalStateException(
-            "You cannot set progress() when you're using a custom view.");
-      }
-      if (indeterminate) {
-        this.indeterminateProgress = true;
-        this.progress = -2;
-      } else {
-        this.indeterminateIsHorizontalProgress = false;
-        this.indeterminateProgress = false;
-        this.progress = -1;
-        this.progressMax = max;
-      }
-      return this;
-    }
-
-    /**
-     * Makes this dialog a progress dialog.
-     *
-     * @param indeterminate If true, an infinite circular spinner is shown. If false, a horizontal
-     *     progress bar is shown that is incremented or set via the built MaterialDialog instance.
-     * @param max When indeterminate is false, the max value the horizontal progress bar can get to.
-     * @param showMinMax For determinate dialogs, the min and max will be displayed to the left
-     *     (start) of the progress bar, e.g. 50/100.
-     * @return An instance of the Builder so calls can be chained.
-     */
-    public Builder progress(boolean indeterminate, int max, boolean showMinMax) {
-      this.showMinMax = showMinMax;
-      return progress(indeterminate, max);
-    }
-
-    /**
-     * hange the format of the small text showing current and maximum units of progress. The default
-     * is "%1d/%2d".
-     */
-    public Builder progressNumberFormat(String format) {
-      this.progressNumberFormat = format;
-      return this;
-    }
-
-    /**
-     * Change the format of the small text showing the percentage of progress. The default is
-     * NumberFormat.getPercentageInstance().
-     */
-    public Builder progressPercentFormat(NumberFormat format) {
-      this.progressPercentFormat = format;
-      return this;
-    }
-
-    /**
-     * By default, indeterminate progress dialogs will use a circular indicator. You can change it
-     * to use a horizontal progress indicator.
-     */
-    public Builder progressIndeterminateStyle(boolean horizontal) {
-      this.indeterminateIsHorizontalProgress = horizontal;
-      return this;
-    }
-
-    public Builder widgetColor(@ColorInt int color) {
-      this.widgetColor = color;
-      this.widgetColorSet = true;
-      return this;
-    }
-
-    public Builder widgetColorRes(@ColorRes int colorRes) {
-      return widgetColor(DialogUtils.getColor(this.context, colorRes));
-    }
-
-    public Builder widgetColorAttr(@AttrRes int colorAttr) {
-      return widgetColor(DialogUtils.resolveColor(this.context, colorAttr));
-    }
-
-    public Builder choiceWidgetColor(@Nullable ColorStateList colorStateList) {
-      this.choiceWidgetColor = colorStateList;
-      return this;
-    }
-
-    public Builder dividerColor(@ColorInt int color) {
-      this.dividerColor = color;
-      this.dividerColorSet = true;
-      return this;
-    }
-
-    public Builder dividerColorRes(@ColorRes int colorRes) {
-      return dividerColor(DialogUtils.getColor(this.context, colorRes));
-    }
-
-    public Builder dividerColorAttr(@AttrRes int colorAttr) {
-      return dividerColor(DialogUtils.resolveColor(this.context, colorAttr));
-    }
-
-    public Builder backgroundColor(@ColorInt int color) {
-      this.backgroundColor = color;
-      return this;
-    }
-
-    public Builder backgroundColorRes(@ColorRes int colorRes) {
-      return backgroundColor(DialogUtils.getColor(this.context, colorRes));
-    }
-
-    public Builder backgroundColorAttr(@AttrRes int colorAttr) {
-      return backgroundColor(DialogUtils.resolveColor(this.context, colorAttr));
-    }
-
-    public Builder onPositive(SingleButtonCallback callback) {
-      this.onPositiveCallback = callback;
-      return this;
-    }
-
-    public Builder onNegative(SingleButtonCallback callback) {
-      this.onNegativeCallback = callback;
-      return this;
-    }
-
-    public Builder onNeutral(SingleButtonCallback callback) {
-      this.onNeutralCallback = callback;
-      return this;
-    }
-
-    public Builder onAny(SingleButtonCallback callback) {
-      this.onAnyCallback = callback;
-      return this;
-    }
-
-    public Builder theme(Theme theme) {
-      this.theme = theme;
-      return this;
-    }
-
-    public Builder cancelable(boolean cancelable) {
-      this.cancelable = cancelable;
-      this.canceledOnTouchOutside = cancelable;
-      return this;
-    }
-
-    public Builder canceledOnTouchOutside(boolean canceledOnTouchOutside) {
-      this.canceledOnTouchOutside = canceledOnTouchOutside;
-      return this;
-    }
-
-    /**
-     * This defaults to true. If set to false, the dialog will not automatically be dismissed when
-     * an action button is pressed, and not automatically dismissed when the user selects a list
-     * item.
-     *
-     * @param dismiss Whether or not to dismiss the dialog automatically.
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder autoDismiss(boolean dismiss) {
-      this.autoDismiss = dismiss;
-      return this;
-    }
-
-    /**
-     * Sets a custom {@link android.support.v7.widget.RecyclerView.Adapter} for the dialog's list
-     *
-     * @param adapter The adapter to set to the list.
-     * @param layoutManager The layout manager to use in the RecyclerView. Pass null to use the
-     *     default linear manager.
-     * @return This Builder object to allow for chaining of calls to set methods
-     */
-    public Builder adapter(
-        RecyclerView.Adapter<?> adapter, @Nullable RecyclerView.LayoutManager layoutManager) {
-      if (this.customView != null) {
-        throw new IllegalStateException(
-            "You cannot set adapter() when " + "you're using a custom view.");
-      }
-      if (layoutManager != null
-          && !(layoutManager instanceof LinearLayoutManager)
-          && !(layoutManager instanceof GridLayoutManager)) {
-        throw new IllegalStateException(
-            "You can currently only use LinearLayoutManager"
-                + " and GridLayoutManager with this library.");
-      }
-      this.adapter = adapter;
-      this.layoutManager = layoutManager;
-      return this;
-    }
-
-    /** Limits the display size of a set icon to 48dp. */
-    public Builder limitIconToDefaultSize() {
-      this.limitIconToDefaultSize = true;
-      return this;
-    }
-
-    public Builder maxIconSize(int maxIconSize) {
-      this.maxIconSize = maxIconSize;
-      return this;
-    }
-
-    public Builder maxIconSizeRes(@DimenRes int maxIconSizeRes) {
-      return maxIconSize((int) this.context.getResources().getDimension(maxIconSizeRes));
-    }
-
-    public Builder showListener(OnShowListener listener) {
-      this.showListener = listener;
-      return this;
-    }
-
-    public Builder dismissListener(OnDismissListener listener) {
-      this.dismissListener = listener;
-      return this;
-    }
-
-    public Builder cancelListener(OnCancelListener listener) {
-      this.cancelListener = listener;
-      return this;
-    }
-
-    public Builder keyListener(OnKeyListener listener) {
-      this.keyListener = listener;
-      return this;
-    }
-
-    /**
-     * Sets action button stacking behavior.
-     *
-     * @param behavior The behavior of the action button stacking logic.
-     * @return The Builder instance so you can chain calls to it.
-     */
-    public Builder stackingBehavior(StackingBehavior behavior) {
-      this.stackingBehavior = behavior;
-      return this;
-    }
-
-    public Builder input(
-        @Nullable CharSequence hint,
-        @Nullable CharSequence prefill,
-        boolean allowEmptyInput,
-        InputCallback callback) {
-      if (this.customView != null) {
-        throw new IllegalStateException(
-            "You cannot set content() when " + "you're using a custom view.");
-      }
-      this.inputCallback = callback;
-      this.inputHint = hint;
-      this.inputPrefill = prefill;
-      this.inputAllowEmpty = allowEmptyInput;
-      return this;
-    }
-
-    public Builder input(
-        @Nullable CharSequence hint, @Nullable CharSequence prefill, InputCallback callback) {
-      return input(hint, prefill, true, callback);
-    }
-
-    public Builder input(
-        @StringRes int hint,
-        @StringRes int prefill,
-        boolean allowEmptyInput,
-        InputCallback callback) {
-      return input(
-          hint == 0 ? null : context.getText(hint),
-          prefill == 0 ? null : context.getText(prefill),
-          allowEmptyInput,
-          callback);
-    }
-
-    public Builder input(@StringRes int hint, @StringRes int prefill, InputCallback callback) {
-      return input(hint, prefill, true, callback);
-    }
-
-    public Builder inputType(int type) {
-      this.inputType = type;
-      return this;
-    }
-
-    public Builder inputRange(
-        @IntRange(from = 0, to = Integer.MAX_VALUE) int minLength,
-        @IntRange(from = -1, to = Integer.MAX_VALUE) int maxLength) {
-      return inputRange(minLength, maxLength, 0);
-    }
-
-    /** @param errorColor Pass in 0 for the default red error color (as specified in guidelines). */
-    public Builder inputRange(
-        @IntRange(from = 0, to = Integer.MAX_VALUE) int minLength,
-        @IntRange(from = -1, to = Integer.MAX_VALUE) int maxLength,
-        @ColorInt int errorColor) {
-      if (minLength < 0) {
-        throw new IllegalArgumentException(
-            "Min length for input dialogs " + "cannot be less than 0.");
-      }
-      this.inputMinLength = minLength;
-      this.inputMaxLength = maxLength;
-      if (errorColor == 0) {
-        this.inputRangeErrorColor = DialogUtils.getColor(context, R.color.md_edittext_error);
-      } else {
-        this.inputRangeErrorColor = errorColor;
-      }
-      if (this.inputMinLength > 0) {
-        this.inputAllowEmpty = false;
-      }
-      return this;
-    }
-
-    /**
-     * Same as #{@link #inputRange(int, int, int)}, but it takes a color resource ID for the error
-     * color.
-     */
-    public Builder inputRangeRes(
-        @IntRange(from = 0, to = Integer.MAX_VALUE) int minLength,
-        @IntRange(from = -1, to = Integer.MAX_VALUE) int maxLength,
-        @ColorRes int errorColor) {
-      return inputRange(minLength, maxLength, DialogUtils.getColor(context, errorColor));
-    }
-
-    public Builder inputFilters(@Nullable InputFilter... filters) {
-      this.inputFilters = filters;
-      return this;
-    }
-
-    public Builder alwaysCallInputCallback() {
-      this.alwaysCallInputCallback = true;
-      return this;
-    }
-
-    public Builder tag(@Nullable Object tag) {
-      this.tag = tag;
-      return this;
-    }
-
-    @UiThread
-    public MaterialDialog build() {
-      return new MaterialDialog(this);
-    }
-
-    @UiThread
-    public MaterialDialog show() {
-      MaterialDialog dialog = build();
-      dialog.show();
-      return dialog;
-    }
-  }
-}

+ 323 - 0
core/src/main/java/com/afollestad/materialdialogs/MaterialDialog.kt

@@ -0,0 +1,323 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+@file:Suppress("unused")
+
+package com.afollestad.materialdialogs
+
+import android.app.Dialog
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.support.annotation.CheckResult
+import android.support.annotation.DrawableRes
+import android.support.annotation.RestrictTo
+import android.support.annotation.RestrictTo.Scope
+import android.support.annotation.StringRes
+import android.view.View
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.afollestad.materialdialogs.Theme.Companion.inferTheme
+import com.afollestad.materialdialogs.WhichButton.NEGATIVE
+import com.afollestad.materialdialogs.WhichButton.NEUTRAL
+import com.afollestad.materialdialogs.WhichButton.POSITIVE
+import com.afollestad.materialdialogs.callbacks.invokeAll
+import com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout.Companion.INDEX_NEGATIVE
+import com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout.Companion.INDEX_NEUTRAL
+import com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout.Companion.INDEX_POSITIVE
+import com.afollestad.materialdialogs.internal.list.DialogAdapter
+import com.afollestad.materialdialogs.internal.list.DialogRecyclerView
+import com.afollestad.materialdialogs.internal.main.DialogLayout
+import com.afollestad.materialdialogs.internal.main.DialogScrollView
+import com.afollestad.materialdialogs.list.getListAdapter
+import com.afollestad.materialdialogs.utilext.isVisible
+import com.afollestad.materialdialogs.utilext.assertOneSet
+import com.afollestad.materialdialogs.utilext.getString
+import com.afollestad.materialdialogs.utilext.hideKeyboard
+import com.afollestad.materialdialogs.utilext.inflate
+import com.afollestad.materialdialogs.utilext.preShow
+import com.afollestad.materialdialogs.utilext.setDefaults
+import com.afollestad.materialdialogs.utilext.setIcon
+import com.afollestad.materialdialogs.utilext.setText
+import com.afollestad.materialdialogs.utilext.setWindowConstraints
+
+typealias DialogCallback = (MaterialDialog) -> Unit
+
+/** @author Aidan Follestad (afollestad) */
+class MaterialDialog(
+  val windowContext: Context
+) : Dialog(windowContext, inferTheme(windowContext).styleRes) {
+
+  /**
+   * A named config map, used like tags for extensions.
+   *
+   * Developers extending functionality of Material Dialogs should not use things
+   * like static variables to store things. They instead should be stored at a dialog
+   * instance level, which is what this provides.
+   */
+  val config: MutableMap<String, Any> = mutableMapOf()
+
+  /** Returns true if auto dismiss is enabled. */
+  var autoDismissEnabled: Boolean = true
+    internal set
+
+  internal val view: DialogLayout = inflate(R.layout.md_dialog_base)
+  private var textViewMessage: TextView? = null
+  internal var contentScrollView: DialogScrollView? = null
+  internal var contentScrollViewFrame: LinearLayout? = null
+  internal var contentRecyclerView: DialogRecyclerView? = null
+  internal var contentCustomView: View? = null
+
+  internal val preShowListeners = mutableListOf<DialogCallback>()
+  internal val showListeners = mutableListOf<DialogCallback>()
+  internal val dismissListeners = mutableListOf<DialogCallback>()
+  internal val cancelListeners = mutableListOf<DialogCallback>()
+
+  private val positiveListeners = mutableListOf<DialogCallback>()
+  private val negativeListeners = mutableListOf<DialogCallback>()
+  private val neutralListeners = mutableListOf<DialogCallback>()
+
+  init {
+    setContentView(view)
+    this.view.dialog = this
+    setWindowConstraints()
+    setDefaults()
+  }
+
+  /**
+   * Shows an drawable to the left of the dialog title.
+   *
+   * @param res The drawable resource to display as the drawable.
+   * @param drawable The drawable to display as the drawable.
+   */
+  @CheckResult
+  fun icon(
+    @DrawableRes res: Int? = null,
+    drawable: Drawable? = null
+  ): MaterialDialog {
+    assertOneSet(res, drawable)
+    setIcon(
+        view.titleLayout.iconView,
+        iconRes = res,
+        icon = drawable
+    )
+    return this
+  }
+
+  /**
+   * Shows a title, or header, at the top of the dialog.
+   *
+   * @param res The string resource to display as the title.
+   * @param text The literal string to display as the title.
+   */
+  @CheckResult
+  fun title(
+    @StringRes res: Int? = null,
+    text: String? = null
+  ): MaterialDialog {
+    assertOneSet(res, text)
+    setText(
+        view.titleLayout.titleView,
+        textRes = res,
+        text = text
+    )
+    return this
+  }
+
+  /**
+   * Shows a message, below the title, and above the action buttons (and checkbox prompt).
+   *
+   * @param res The string resource to display as the message.
+   * @param text The literal string to display as the message.
+   */
+  @CheckResult
+  fun message(
+    @StringRes res: Int? = null,
+    text: CharSequence? = null
+  ): MaterialDialog {
+    if (this.contentCustomView != null) {
+      throw IllegalStateException("message() should be used BEFORE customView().")
+    }
+    addContentScrollView()
+    addContentMessageView(res, text)
+    return this
+  }
+
+  /**
+   * Shows a positive action button, in the far right at the bottom of the dialog.
+   *
+   * @param res The string resource to display on the title.
+   * @param text The literal string to display on the button.
+   * @param click A listener to invoke when the button is pressed.
+   */
+  @CheckResult
+  fun positiveButton(
+    @StringRes res: Int? = null,
+    text: CharSequence? = null,
+    click: DialogCallback? = null
+  ): MaterialDialog {
+    if (click != null) {
+      positiveListeners.add(click)
+    }
+
+    val btn = view.buttonsLayout.actionButtons[INDEX_POSITIVE]
+    if (res == null && text == null && btn.isVisible()) {
+      // Didn't receive text and the button is already setup,
+      // so just stop with the added listener.
+      return this
+    }
+
+    setText(
+        btn,
+        textRes = res,
+        text = text,
+        fallback = android.R.string.ok
+    )
+    return this
+  }
+
+  /**
+   * Shows a negative action button, to the left of the positive action button (or at the far
+   * right if there is no positive action button).
+   *
+   * @param res The string resource to display on the title.
+   * @param text The literal string to display on the button.
+   * @param click A listener to invoke when the button is pressed.
+   */
+  @CheckResult
+  fun negativeButton(
+    @StringRes res: Int? = null,
+    text: CharSequence? = null,
+    click: DialogCallback? = null
+  ): MaterialDialog {
+    if (click != null) {
+      negativeListeners.add(click)
+    }
+
+    val btn = view.buttonsLayout.actionButtons[INDEX_NEGATIVE]
+    if (res == null && text == null && btn.isVisible()) {
+      // Didn't receive text and the button is already setup,
+      // so just stop with the added listener.
+      return this
+    }
+
+    setText(
+        btn,
+        textRes = res,
+        text = text,
+        fallback = android.R.string.cancel
+    )
+    return this
+  }
+
+  @CheckResult
+  @Deprecated(
+      "Use of neutral buttons is discouraged, see " +
+          "https://material.io/design/components/dialogs.html#actions."
+  )
+  fun neutralButton(
+    @StringRes res: Int? = null,
+    text: CharSequence? = null,
+    click: DialogCallback? = null
+  ): MaterialDialog {
+    if (click != null) {
+      neutralListeners.add(click)
+    }
+
+    val btn = view.buttonsLayout.actionButtons[INDEX_NEUTRAL]
+    if (res == null && text == null && btn.isVisible()) {
+      // Didn't receive text and the button is already setup,
+      // so just stop with the added listener.
+      return this
+    }
+
+    setText(
+        btn,
+        textRes = res,
+        text = text
+    )
+    return this
+  }
+
+  /**
+   * Turns off auto dismiss. Action button and list item clicks won't dismiss the dialog on their
+   * own. You have to handle dismissing the dialog manually with the [dismiss] method.
+   */
+  @CheckResult
+  fun noAutoDismiss(): MaterialDialog {
+    this.autoDismissEnabled = false
+    return this
+  }
+
+  /** Turns debug mode on or off. Draws spec guides over dialog views. */
+  @CheckResult
+  fun debugMode(debugMode: Boolean = true): MaterialDialog {
+    this.view.debugMode = debugMode
+    return this
+  }
+
+  /** Opens the dialog. */
+  override fun show() {
+    preShow()
+    super.show()
+  }
+
+  /** Applies multiple properties to the dialog and opens it. */
+  inline fun show(func: MaterialDialog.() -> Unit): MaterialDialog {
+    this.func()
+    this.show()
+    return this
+  }
+
+  override fun dismiss() {
+    hideKeyboard()
+    super.dismiss()
+  }
+
+  @RestrictTo(Scope.LIBRARY_GROUP)
+  fun invalidateDividers(
+    scrolledDown: Boolean,
+    atBottom: Boolean
+  ) = view.invalidateDividers(scrolledDown, atBottom)
+
+  @RestrictTo(Scope.LIBRARY_GROUP)
+  fun isContentScrollViewAdded() = this.contentScrollView != null
+
+  internal fun onActionButtonClicked(which: WhichButton) {
+    when (which) {
+      POSITIVE -> {
+        positiveListeners.invokeAll(this)
+        val adapter = getListAdapter() as? DialogAdapter<*, *>
+        adapter?.positiveButtonClicked()
+      }
+      NEGATIVE -> negativeListeners.invokeAll(this)
+      NEUTRAL -> neutralListeners.invokeAll(this)
+    }
+    if (autoDismissEnabled) {
+      dismiss()
+    }
+  }
+
+  internal fun addContentScrollView() {
+    if (this.contentScrollView == null) {
+      this.contentScrollView = inflate(R.layout.md_dialog_stub_scrollview, this.view)
+      this.contentScrollView!!.rootView = this.view
+      this.contentScrollViewFrame = this.contentScrollView!!.getChildAt(0) as LinearLayout
+      this.view.addView(this.contentScrollView, 1)
+    }
+  }
+
+  private fun addContentMessageView(@StringRes res: Int?, text: CharSequence?) {
+    if (this.textViewMessage == null) {
+      this.textViewMessage = inflate(
+          R.layout.md_dialog_stub_message,
+          this.contentScrollViewFrame!!
+      )
+      this.contentScrollViewFrame!!.addView(this.textViewMessage)
+    }
+    assertOneSet(res, text)
+    this.textViewMessage!!.text = text ?: getString(res)
+  }
+}

+ 0 - 11
core/src/main/java/com/afollestad/materialdialogs/StackingBehavior.java

@@ -1,11 +0,0 @@
-package com.afollestad.materialdialogs;
-
-/** @author Aidan Follestad (afollestad) */
-public enum StackingBehavior {
-  /** The action buttons are always stacked vertically. */
-  ALWAYS,
-  /** The action buttons are stacked vertically IF it is necessary for them to fit in the dialog. */
-  ADAPTIVE,
-  /** The action buttons are never stacked, even if they should be. */
-  NEVER
-}

+ 0 - 7
core/src/main/java/com/afollestad/materialdialogs/Theme.java

@@ -1,7 +0,0 @@
-package com.afollestad.materialdialogs;
-
-/** @author Aidan Follestad (afollestad) */
-public enum Theme {
-  LIGHT,
-  DARK
-}

+ 22 - 0
core/src/main/java/com/afollestad/materialdialogs/Theme.kt

@@ -0,0 +1,22 @@
+package com.afollestad.materialdialogs
+
+import android.R.attr
+import android.content.Context
+import android.support.annotation.StyleRes
+import com.afollestad.materialdialogs.utilext.getColor
+import com.afollestad.materialdialogs.utilext.isColorDark
+
+internal enum class Theme(
+  @StyleRes val styleRes: Int
+) {
+  LIGHT(R.style.MD_Light),
+  DARK(R.style.MD_Dark);
+
+  companion object {
+    fun inferTheme(context: Context): Theme {
+      val isPrimaryDark =
+        getColor(context = context, attr = attr.textColorPrimary).isColorDark()
+      return if (isPrimaryDark) LIGHT else DARK
+    }
+  }
+}

+ 20 - 0
core/src/main/java/com/afollestad/materialdialogs/WhichButton.kt

@@ -0,0 +1,20 @@
+package com.afollestad.materialdialogs
+
+import com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout.Companion.INDEX_NEGATIVE
+import com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout.Companion.INDEX_NEUTRAL
+import com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout.Companion.INDEX_POSITIVE
+
+enum class WhichButton(val index: Int) {
+  POSITIVE(INDEX_POSITIVE),
+  NEGATIVE(INDEX_NEGATIVE),
+  NEUTRAL(INDEX_NEUTRAL);
+
+  companion object {
+    fun fromIndex(index: Int) = when (index) {
+      INDEX_POSITIVE -> POSITIVE
+      INDEX_NEGATIVE -> NEGATIVE
+      INDEX_NEUTRAL -> NEUTRAL
+      else -> throw IndexOutOfBoundsException("$index is not an action button index.")
+    }
+  }
+}

+ 16 - 0
core/src/main/java/com/afollestad/materialdialogs/actions/DialogActionExt.kt

@@ -0,0 +1,16 @@
+package com.afollestad.materialdialogs.actions
+
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.WhichButton
+
+/** Enables or disables an action button. */
+fun MaterialDialog.setActionButtonEnabled(
+  which: WhichButton,
+  enabled: Boolean
+): MaterialDialog {
+  view.buttonsLayout.actionButtons[which.index].isEnabled = enabled
+  return this
+}
+
+/** Returns true if the dialog has visible action buttons. */
+fun MaterialDialog.hasActionButtons() = view.buttonsLayout.visibleButtons.isNotEmpty()

+ 65 - 0
core/src/main/java/com/afollestad/materialdialogs/callbacks/DialogCallbackExt.kt

@@ -0,0 +1,65 @@
+package com.afollestad.materialdialogs.callbacks
+
+import com.afollestad.materialdialogs.DialogCallback
+import com.afollestad.materialdialogs.MaterialDialog
+
+/**
+ * Adds a listener that's invoked right before the dialog is [show]'n. If this is called
+ * multiple times, it appends additional callbacks, rather than overwriting.
+ */
+fun MaterialDialog.onPreShow(callback: DialogCallback): MaterialDialog {
+  this.preShowListeners.add(callback)
+  return this
+}
+
+/**
+ * Adds a listener that's invoked when the dialog is [show]'n. If this is called
+ * multiple times, it appends additional callbacks, rather than overwriting.
+ */
+fun MaterialDialog.onShow(callback: DialogCallback): MaterialDialog {
+  this.showListeners.add(callback)
+  if (this.isShowing) {
+    // Already showing, invoke now
+    this.showListeners.invokeAll(this)
+  }
+  if (this.showListeners.isNotEmpty()) {
+    // Already set the base show listener
+    return this
+  }
+  setOnShowListener { this.showListeners.invokeAll(this) }
+  return this
+}
+
+/**
+ * Adds a listener that's invoked when the dialog is [dismiss]'d. If this is called
+ * multiple times, it appends additional callbacks, rather than overwriting.
+ */
+fun MaterialDialog.onDismiss(callback: DialogCallback): MaterialDialog {
+  this.dismissListeners.add(callback)
+  if (this.dismissListeners.isNotEmpty()) {
+    // Already set the base dismiss listener
+    return this
+  }
+  setOnDismissListener { dismissListeners.invokeAll(this) }
+  return this
+}
+
+/**
+ * Adds a listener that's invoked when the dialog is [cancel]'d. If this is called
+ * multiple times, it appends additional callbacks, rather than overwriting.
+ */
+fun MaterialDialog.onCancel(callback: DialogCallback): MaterialDialog {
+  this.cancelListeners.add(callback)
+  if (this.cancelListeners.isNotEmpty()) {
+    // Already set the base cancel listener
+    return this
+  }
+  setOnCancelListener { cancelListeners.invokeAll(this) }
+  return this
+}
+
+internal fun MutableList<DialogCallback>.invokeAll(dialog: MaterialDialog) {
+  for (callback in this) {
+    callback.invoke(dialog)
+  }
+}

+ 52 - 0
core/src/main/java/com/afollestad/materialdialogs/checkbox/DialogCheckboxExt.kt

@@ -0,0 +1,52 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+@file:Suppress("unused")
+
+package com.afollestad.materialdialogs.checkbox
+
+import android.support.annotation.CheckResult
+import android.support.annotation.StringRes
+import android.view.View
+import android.widget.CheckBox
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.utilext.assertOneSet
+import com.afollestad.materialdialogs.utilext.getString
+
+typealias BooleanCallback = ((Boolean) -> Unit)?
+
+@CheckResult
+fun MaterialDialog.getCheckBoxPrompt(): CheckBox {
+  return view.buttonsLayout.checkBoxPrompt
+}
+
+@CheckResult
+fun MaterialDialog.isCheckPromptChecked() = getCheckBoxPrompt().isChecked
+
+/**
+ * @param res The string resource to display for the checkbox label.
+ * @param text The literal string to display for the checkbox label.
+ * @param isCheckedDefault Whether or not the checkbox is initially checked.
+ * @param onToggle A listener invoked when the checkbox is checked or unchecked.
+ */
+@CheckResult
+fun MaterialDialog.checkBoxPrompt(
+  @StringRes res: Int = 0,
+  text: String? = null,
+  isCheckedDefault: Boolean = false,
+  onToggle: BooleanCallback
+): MaterialDialog {
+  assertOneSet(res, text)
+  view.buttonsLayout.checkBoxPrompt.apply {
+    this.visibility = View.VISIBLE
+    this.text = text ?: getString(res)
+    this.isChecked = isCheckedDefault
+    this.setOnCheckedChangeListener { _, checked ->
+      onToggle?.invoke(checked)
+    }
+  }
+  return this
+}

+ 64 - 0
core/src/main/java/com/afollestad/materialdialogs/customview/DialogCustomViewExt.kt

@@ -0,0 +1,64 @@
+/*
+ * Licensed under Apache-2.0
+ *
+ * Designed an developed by Aidan Follestad (afollestad)
+ */
+
+package com.afollestad.materialdialogs.customview
+
+import android.support.annotation.CheckResult
+import android.support.annotation.LayoutRes
+import android.view.View
+import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.R
+import com.afollestad.materialdialogs.utilext.dimenPx
+import com.afollestad.materialdialogs.utilext.topMargin
+import com.afollestad.materialdialogs.utilext.updateMargin
+import com.afollestad.materialdialogs.utilext.updatePadding
+import com.afollestad.materialdialogs.utilext.assertOneSet
+import com.afollestad.materialdialogs.utilext.inflate
+
+@CheckResult
+fun MaterialDialog.getCustomView(): View? {
+  return contentCustomView
+}
+
+/**
+ * Sets a custom view to display in the dialog, below the title and above the action buttons
+ * (and checkbox prompt).
+ *
+ * @param viewRes The layout resource to inflate as the custom view.
+ * @param view The view to insert as the custom view.
+ * @param scrollable Whether or not the custom view is automatically wrapped in a ScrollView.
+ */
+@CheckResult
+fun MaterialDialog.customView(
+  @LayoutRes viewRes: Int? = null,
+  view: View? = null,
+  scrollable: Boolean = false
+): MaterialDialog {
+  if (this.contentRecyclerView != null) {
+    throw IllegalStateException(
+        "This dialog has already been setup with another type " +
+            "(e.g. list, message, input, etc.)"
+    )
+  }
+  assertOneSet(viewRes, view)
+  if (scrollable || this.contentScrollViewFrame != null) {
+    addContentScrollView()
+    this.contentCustomView = view ?: inflate(viewRes!!, this.contentScrollViewFrame!!)
+    if (!scrollable) {
+      // We didn't explicitly want this view to be scrollable but we already had existing
+      // scroll content. So, add top margin to separate a bit.
+      this.contentCustomView!!.apply {
+        updateMargin(top = topMargin() + dimenPx(R.dimen.md_dialog_frame_margin_vertical_less))
+        updatePadding(bottom = 0)
+      }
+    }
+    this.contentScrollViewFrame!!.addView(this.contentCustomView)
+  } else {
+    this.contentCustomView = view ?: inflate(viewRes!!, this.view)
+    this.view.addView(this.contentCustomView, 1)
+  }
+  return this
+}

+ 0 - 28
core/src/main/java/com/afollestad/materialdialogs/internal/AllCapsTransformationMethod.java

@@ -1,28 +0,0 @@
-package com.afollestad.materialdialogs.internal;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.text.method.TransformationMethod;
-import android.view.View;
-import java.util.Locale;
-
-class AllCapsTransformationMethod implements TransformationMethod {
-  private Locale mLocale;
-
-  AllCapsTransformationMethod(Context context) {
-    mLocale = context.getResources().getConfiguration().locale;
-  }
-
-  @Override
-  public CharSequence getTransformation(CharSequence source, View view) {
-    return source != null ? source.toString().toUpperCase(mLocale) : null;
-  }
-
-  @Override
-  public void onFocusChanged(
-      View view,
-      CharSequence sourceText,
-      boolean focused,
-      int direction,
-      Rect previouslyFocusedRect) {}
-}

+ 0 - 8
core/src/main/java/com/afollestad/materialdialogs/internal/MDAdapter.java

@@ -1,8 +0,0 @@
-package com.afollestad.materialdialogs.internal;
-
-import com.afollestad.materialdialogs.MaterialDialog;
-
-/** @author Aidan Follestad (afollestad) */
-public interface MDAdapter {
-  void setDialog(MaterialDialog dialog);
-}

+ 0 - 93
core/src/main/java/com/afollestad/materialdialogs/internal/MDButton.java

@@ -1,93 +0,0 @@
-package com.afollestad.materialdialogs.internal;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.GravityEnum;
-import com.afollestad.materialdialogs.R;
-import com.afollestad.materialdialogs.util.DialogUtils;
-
-/** @author Kevin Barry (teslacoil) 4/02/2015 */
-@SuppressLint("AppCompatCustomView")
-public class MDButton extends TextView {
-
-  private boolean stacked = false;
-  private GravityEnum stackedGravity;
-
-  private int stackedEndPadding;
-  private Drawable stackedBackground;
-  private Drawable defaultBackground;
-
-  public MDButton(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    init(context);
-  }
-
-  public MDButton(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    init(context);
-  }
-
-  private void init(Context context) {
-    stackedEndPadding =
-        context.getResources().getDimensionPixelSize(R.dimen.md_dialog_frame_margin);
-    stackedGravity = GravityEnum.END;
-  }
-
-  /**
-   * Set if the button should be displayed in stacked mode. This should only be called from
-   * MDRootLayout's onMeasure, and we must be measured after calling this.
-   */
-  /* package */ void setStacked(boolean stacked, boolean force) {
-    if (this.stacked != stacked || force) {
-
-      setGravity(
-          stacked ? (Gravity.CENTER_VERTICAL | stackedGravity.getGravityInt()) : Gravity.CENTER);
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-        //noinspection ResourceType
-        setTextAlignment(stacked ? stackedGravity.getTextAlignment() : TEXT_ALIGNMENT_CENTER);
-      }
-
-      DialogUtils.setBackgroundCompat(this, stacked ? stackedBackground : defaultBackground);
-      if (stacked) {
-        setPadding(stackedEndPadding, getPaddingTop(), stackedEndPadding, getPaddingBottom());
-      } /* Else the padding was properly reset by the drawable */
-
-      this.stacked = stacked;
-    }
-  }
-
-  public void setStackedGravity(GravityEnum gravity) {
-    stackedGravity = gravity;
-  }
-
-  public void setStackedSelector(Drawable d) {
-    stackedBackground = d;
-    if (stacked) {
-      setStacked(true, true);
-    }
-  }
-
-  public void setDefaultSelector(Drawable d) {
-    defaultBackground = d;
-    if (!stacked) {
-      setStacked(false, true);
-    }
-  }
-
-  public void setAllCapsCompat(boolean allCaps) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-      setAllCaps(allCaps);
-    } else {
-      if (allCaps) {
-        setTransformationMethod(new AllCapsTransformationMethod(getContext()));
-      } else {
-        setTransformationMethod(null);
-      }
-    }
-  }
-}

+ 0 - 650
core/src/main/java/com/afollestad/materialdialogs/internal/MDRootLayout.java

@@ -1,650 +0,0 @@
-package com.afollestad.materialdialogs.internal;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.os.Build;
-import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.webkit.WebView;
-import android.widget.AdapterView;
-import android.widget.CheckBox;
-import android.widget.ScrollView;
-import com.afollestad.materialdialogs.GravityEnum;
-import com.afollestad.materialdialogs.R;
-import com.afollestad.materialdialogs.StackingBehavior;
-import com.afollestad.materialdialogs.util.DialogUtils;
-
-/**
- * @author Kevin Barry (teslacoil) 4/02/2015 This is the top level view for all MaterialDialogs It
- *     handles the layout of: titleFrame (md_stub_titleframe) content (text, custom view, listview,
- *     etc) buttonDefault... (either stacked or horizontal)
- */
-public class MDRootLayout extends ViewGroup {
-
-  private static final int INDEX_NEUTRAL = 0;
-  private static final int INDEX_NEGATIVE = 1;
-  private static final int INDEX_POSITIVE = 2;
-  private final MDButton[] buttons = new MDButton[3];
-  private int maxHeight;
-  private View titleBar;
-  private View content;
-  private CheckBox checkPrompt;
-  private boolean drawTopDivider = false;
-  private boolean drawBottomDivider = false;
-  private StackingBehavior stackBehavior = StackingBehavior.ADAPTIVE;
-  private boolean isStacked = false;
-  private boolean useFullPadding = true;
-  private boolean reducePaddingNoTitleNoButtons;
-  private boolean noTitleNoPadding;
-
-  private int noTitlePaddingFull;
-  private int buttonPaddingFull;
-  private int buttonBarHeight;
-
-  private GravityEnum buttonGravity = GravityEnum.START;
-
-  /* Margin from dialog frame to first button */
-  private int buttonHorizontalEdgeMargin;
-
-  private Paint dividerPaint;
-
-  private ViewTreeObserver.OnScrollChangedListener topOnScrollChangedListener;
-  private ViewTreeObserver.OnScrollChangedListener bottomOnScrollChangedListener;
-  private int dividerWidth;
-
-  public MDRootLayout(Context context) {
-    super(context);
-    init(context, null, 0);
-  }
-
-  public MDRootLayout(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    init(context, attrs, 0);
-  }
-
-  @TargetApi(Build.VERSION_CODES.HONEYCOMB)
-  public MDRootLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-    super(context, attrs, defStyleAttr);
-    init(context, attrs, defStyleAttr);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  public MDRootLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-    super(context, attrs, defStyleAttr, defStyleRes);
-    init(context, attrs, defStyleAttr);
-  }
-
-  private static boolean isVisible(@Nullable View v) {
-    boolean visible = v != null && v.getVisibility() != View.GONE;
-    if (visible && v instanceof MDButton) {
-      visible = ((MDButton) v).getText().toString().trim().length() > 0;
-    }
-    return visible;
-  }
-
-  public static boolean canRecyclerViewScroll(@Nullable RecyclerView view) {
-    return view != null
-        && view.getLayoutManager() != null
-        && view.getLayoutManager().canScrollVertically();
-  }
-
-  private static boolean canScrollViewScroll(ScrollView sv) {
-    if (sv.getChildCount() == 0) {
-      return false;
-    }
-    final int childHeight = sv.getChildAt(0).getMeasuredHeight();
-    return sv.getMeasuredHeight() - sv.getPaddingTop() - sv.getPaddingBottom() < childHeight;
-  }
-
-  private static boolean canWebViewScroll(WebView view) {
-    //noinspection deprecation
-    return view.getMeasuredHeight() < view.getContentHeight() * view.getScale();
-  }
-
-  private static boolean canAdapterViewScroll(AdapterView lv) {
-    /* Force it to layout it's children */
-    if (lv.getLastVisiblePosition() == -1) {
-      return false;
-    }
-
-    /* We can scroll if the first or last item is not visible */
-    boolean firstItemVisible = lv.getFirstVisiblePosition() == 0;
-    boolean lastItemVisible = lv.getLastVisiblePosition() == lv.getCount() - 1;
-
-    if (firstItemVisible && lastItemVisible && lv.getChildCount() > 0) {
-      /* Or the first item's top is above or own top */
-      if (lv.getChildAt(0).getTop() < lv.getPaddingTop()) {
-        return true;
-      }
-      /* or the last item's bottom is beyond our own bottom */
-      return lv.getChildAt(lv.getChildCount() - 1).getBottom()
-          > lv.getHeight() - lv.getPaddingBottom();
-    }
-
-    return true;
-  }
-
-  /**
-   * Find the view touching the bottom of this ViewGroup. Non visible children are ignored, however
-   * getChildDrawingOrder is not taking into account for simplicity and because it behaves
-   * inconsistently across platform versions.
-   *
-   * @return View touching the bottom of this ViewGroup or null
-   */
-  @Nullable
-  private static View getBottomView(@Nullable ViewGroup viewGroup) {
-    if (viewGroup == null || viewGroup.getChildCount() == 0) {
-      return null;
-    }
-    View bottomView = null;
-    for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
-      View child = viewGroup.getChildAt(i);
-      if (child.getVisibility() == View.VISIBLE
-          && child.getBottom() == viewGroup.getMeasuredHeight()) {
-        bottomView = child;
-        break;
-      }
-    }
-    return bottomView;
-  }
-
-  @Nullable
-  private static View getTopView(@Nullable ViewGroup viewGroup) {
-    if (viewGroup == null || viewGroup.getChildCount() == 0) {
-      return null;
-    }
-    View topView = null;
-    for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
-      View child = viewGroup.getChildAt(i);
-      if (child.getVisibility() == View.VISIBLE && child.getTop() == 0) {
-        topView = child;
-        break;
-      }
-    }
-    return topView;
-  }
-
-  private void init(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-    Resources r = context.getResources();
-
-    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MDRootLayout, defStyleAttr, 0);
-    reducePaddingNoTitleNoButtons =
-        a.getBoolean(R.styleable.MDRootLayout_md_reduce_padding_no_title_no_buttons, true);
-    a.recycle();
-
-    noTitlePaddingFull = r.getDimensionPixelSize(R.dimen.md_notitle_vertical_padding);
-    buttonPaddingFull = r.getDimensionPixelSize(R.dimen.md_button_frame_vertical_padding);
-
-    buttonHorizontalEdgeMargin = r.getDimensionPixelSize(R.dimen.md_button_padding_frame_side);
-    buttonBarHeight = r.getDimensionPixelSize(R.dimen.md_button_height);
-
-    dividerPaint = new Paint();
-    dividerWidth = r.getDimensionPixelSize(R.dimen.md_divider_height);
-    dividerPaint.setColor(DialogUtils.resolveColor(context, R.attr.md_divider_color));
-    setWillNotDraw(false);
-  }
-
-  public void setMaxHeight(int maxHeight) {
-    this.maxHeight = maxHeight;
-  }
-
-  public void noTitleNoPadding() {
-    noTitleNoPadding = true;
-  }
-
-  @Override
-  public void onFinishInflate() {
-    super.onFinishInflate();
-    for (int i = 0; i < getChildCount(); i++) {
-      View v = getChildAt(i);
-      if (v.getId() == R.id.md_titleFrame) {
-        titleBar = v;
-      } else if (v.getId() == R.id.md_buttonDefaultNeutral) {
-        buttons[INDEX_NEUTRAL] = (MDButton) v;
-      } else if (v.getId() == R.id.md_buttonDefaultNegative) {
-        buttons[INDEX_NEGATIVE] = (MDButton) v;
-      } else if (v.getId() == R.id.md_buttonDefaultPositive) {
-        buttons[INDEX_POSITIVE] = (MDButton) v;
-      } else if (v.getId() == R.id.md_promptCheckbox) {
-        checkPrompt = (CheckBox) v;
-      } else {
-        content = v;
-      }
-    }
-  }
-
-  @Override
-  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-    int width = MeasureSpec.getSize(widthMeasureSpec);
-    int height = MeasureSpec.getSize(heightMeasureSpec);
-
-    if (height > maxHeight) {
-      height = maxHeight;
-    }
-
-    useFullPadding = true;
-    boolean hasButtons = false;
-
-    final boolean stacked;
-    if (stackBehavior == StackingBehavior.ALWAYS) {
-      stacked = true;
-    } else if (stackBehavior == StackingBehavior.NEVER) {
-      stacked = false;
-    } else {
-      int buttonsWidth = 0;
-      for (MDButton button : buttons) {
-        if (button != null && isVisible(button)) {
-          button.setStacked(false, false);
-          measureChild(button, widthMeasureSpec, heightMeasureSpec);
-          buttonsWidth += button.getMeasuredWidth();
-          hasButtons = true;
-        }
-      }
-
-      int buttonBarPadding =
-          getContext().getResources().getDimensionPixelSize(R.dimen.md_neutral_button_margin);
-      final int buttonFrameWidth = width - 2 * buttonBarPadding;
-      stacked = buttonsWidth > buttonFrameWidth;
-    }
-
-    int stackedHeight = 0;
-    isStacked = stacked;
-    if (stacked) {
-      for (MDButton button : buttons) {
-        if (button != null && isVisible(button)) {
-          button.setStacked(true, false);
-          measureChild(button, widthMeasureSpec, heightMeasureSpec);
-          stackedHeight += button.getMeasuredHeight();
-          hasButtons = true;
-        }
-      }
-    }
-
-    int availableHeight = height;
-    int fullPadding = 0;
-    int minPadding = 0;
-    if (hasButtons) {
-      if (isStacked) {
-        availableHeight -= stackedHeight;
-        fullPadding += 2 * buttonPaddingFull;
-        minPadding += 2 * buttonPaddingFull;
-      } else {
-        availableHeight -= buttonBarHeight;
-        fullPadding += 2 * buttonPaddingFull;
-        /* No minPadding */
-      }
-    } else {
-      /* Content has 8dp, we add 16dp and get 24dp, the frame margin */
-      fullPadding += 2 * buttonPaddingFull;
-    }
-
-    if (isVisible(titleBar)) {
-      titleBar.measure(
-          MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.UNSPECIFIED);
-      availableHeight -= titleBar.getMeasuredHeight();
-    } else if (!noTitleNoPadding) {
-      fullPadding += noTitlePaddingFull;
-    }
-
-    if (isVisible(content)) {
-      content.measure(
-          MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-          MeasureSpec.makeMeasureSpec(availableHeight - minPadding, MeasureSpec.AT_MOST));
-
-      if (content.getMeasuredHeight() <= availableHeight - fullPadding) {
-        if (!reducePaddingNoTitleNoButtons || isVisible(titleBar) || hasButtons) {
-          useFullPadding = true;
-          availableHeight -= content.getMeasuredHeight() + fullPadding;
-        } else {
-          useFullPadding = false;
-          availableHeight -= content.getMeasuredHeight() + minPadding;
-        }
-      } else {
-        useFullPadding = false;
-        availableHeight = 0;
-      }
-    }
-
-    setMeasuredDimension(width, height - availableHeight);
-  }
-
-  @Override
-  public void onDraw(Canvas canvas) {
-    super.onDraw(canvas);
-
-    if (content != null) {
-      if (drawTopDivider) {
-        int y = content.getTop();
-        canvas.drawRect(0, y - dividerWidth, getMeasuredWidth(), y, dividerPaint);
-      }
-
-      if (drawBottomDivider) {
-        int y = content.getBottom();
-        if (checkPrompt != null && checkPrompt.getVisibility() == View.GONE) {
-          y = checkPrompt.getTop();
-        }
-        canvas.drawRect(0, y, getMeasuredWidth(), y + dividerWidth, dividerPaint);
-      }
-    }
-  }
-
-  @Override
-  protected void onLayout(boolean changed, final int l, int t, final int r, int b) {
-    if (isVisible(titleBar)) {
-      int height = titleBar.getMeasuredHeight();
-      titleBar.layout(l, t, r, t + height);
-      t += height;
-    } else if (!noTitleNoPadding && useFullPadding) {
-      t += noTitlePaddingFull;
-    }
-
-    if (isVisible(content)) {
-      content.layout(l, t, r, t + content.getMeasuredHeight());
-    }
-
-    if (isStacked) {
-      b -= buttonPaddingFull;
-      for (MDButton mButton : buttons) {
-        if (isVisible(mButton)) {
-          mButton.layout(l, b - mButton.getMeasuredHeight(), r, b);
-          b -= mButton.getMeasuredHeight();
-        }
-      }
-    } else {
-      int barTop;
-      int barBottom = b;
-      if (useFullPadding) {
-        barBottom -= buttonPaddingFull;
-      }
-      barTop = barBottom - buttonBarHeight;
-      /* START:
-        Neutral   Negative  Positive
-
-        CENTER:
-        Negative  Neutral   Positive
-
-        END:
-        Positive  Negative  Neutral
-
-        (With no Positive, Negative takes it's place except for CENTER)
-      */
-      int offset = buttonHorizontalEdgeMargin;
-
-      /* Used with CENTER gravity */
-      int neutralLeft = -1;
-      int neutralRight = -1;
-
-      if (isVisible(buttons[INDEX_POSITIVE])) {
-        int bl, br;
-        if (buttonGravity == GravityEnum.END) {
-          bl = l + offset;
-          br = bl + buttons[INDEX_POSITIVE].getMeasuredWidth();
-        } else {
-          /* START || CENTER */
-          br = r - offset;
-          bl = br - buttons[INDEX_POSITIVE].getMeasuredWidth();
-          neutralRight = bl;
-        }
-        buttons[INDEX_POSITIVE].layout(bl, barTop, br, barBottom);
-        offset += buttons[INDEX_POSITIVE].getMeasuredWidth();
-      }
-
-      if (isVisible(buttons[INDEX_NEGATIVE])) {
-        int bl, br;
-        if (buttonGravity == GravityEnum.END) {
-          bl = l + offset;
-          br = bl + buttons[INDEX_NEGATIVE].getMeasuredWidth();
-        } else if (buttonGravity == GravityEnum.START) {
-          br = r - offset;
-          bl = br - buttons[INDEX_NEGATIVE].getMeasuredWidth();
-        } else {
-          /* CENTER */
-          bl = l + buttonHorizontalEdgeMargin;
-          br = bl + buttons[INDEX_NEGATIVE].getMeasuredWidth();
-          neutralLeft = br;
-        }
-        buttons[INDEX_NEGATIVE].layout(bl, barTop, br, barBottom);
-      }
-
-      if (isVisible(buttons[INDEX_NEUTRAL])) {
-        int bl, br;
-        if (buttonGravity == GravityEnum.END) {
-          br = r - buttonHorizontalEdgeMargin;
-          bl = br - buttons[INDEX_NEUTRAL].getMeasuredWidth();
-        } else if (buttonGravity == GravityEnum.START) {
-          bl = l + buttonHorizontalEdgeMargin;
-          br = bl + buttons[INDEX_NEUTRAL].getMeasuredWidth();
-        } else {
-          /* CENTER */
-          if (neutralLeft == -1 && neutralRight != -1) {
-            neutralLeft = neutralRight - buttons[INDEX_NEUTRAL].getMeasuredWidth();
-          } else if (neutralRight == -1 && neutralLeft != -1) {
-            neutralRight = neutralLeft + buttons[INDEX_NEUTRAL].getMeasuredWidth();
-          } else if (neutralRight == -1) {
-            neutralLeft = (r - l) / 2 - buttons[INDEX_NEUTRAL].getMeasuredWidth() / 2;
-            neutralRight = neutralLeft + buttons[INDEX_NEUTRAL].getMeasuredWidth();
-          }
-          bl = neutralLeft;
-          br = neutralRight;
-        }
-
-        buttons[INDEX_NEUTRAL].layout(bl, barTop, br, barBottom);
-      }
-    }
-
-    setUpDividersVisibility(content, true, true);
-  }
-
-  public void setStackingBehavior(StackingBehavior behavior) {
-    stackBehavior = behavior;
-    invalidate();
-  }
-
-  public void setDividerColor(int color) {
-    dividerPaint.setColor(color);
-    invalidate();
-  }
-
-  public void setButtonGravity(GravityEnum gravity) {
-    buttonGravity = gravity;
-    invertGravityIfNecessary();
-  }
-
-  private void invertGravityIfNecessary() {
-    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
-      return;
-    }
-    Configuration config = getResources().getConfiguration();
-    if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
-      switch (buttonGravity) {
-        case START:
-          buttonGravity = GravityEnum.END;
-          break;
-        case END:
-          buttonGravity = GravityEnum.START;
-          break;
-      }
-    }
-  }
-
-  public void setButtonStackedGravity(GravityEnum gravity) {
-    for (MDButton mButton : buttons) {
-      if (mButton != null) {
-        mButton.setStackedGravity(gravity);
-      }
-    }
-  }
-
-  private void setUpDividersVisibility(
-      @Nullable final View view, final boolean setForTop, final boolean setForBottom) {
-    if (view == null) {
-      return;
-    }
-    if (view instanceof ScrollView) {
-      final ScrollView sv = (ScrollView) view;
-      if (canScrollViewScroll(sv)) {
-        addScrollListener(sv, setForTop, setForBottom);
-      } else {
-        if (setForTop) {
-          drawTopDivider = false;
-        }
-        if (setForBottom) {
-          drawBottomDivider = false;
-        }
-      }
-    } else if (view instanceof AdapterView) {
-      final AdapterView sv = (AdapterView) view;
-      if (canAdapterViewScroll(sv)) {
-        addScrollListener(sv, setForTop, setForBottom);
-      } else {
-        if (setForTop) {
-          drawTopDivider = false;
-        }
-        if (setForBottom) {
-          drawBottomDivider = false;
-        }
-      }
-    } else if (view instanceof WebView) {
-      view.getViewTreeObserver()
-          .addOnPreDrawListener(
-              new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                  if (view.getMeasuredHeight() != 0) {
-                    if (!canWebViewScroll((WebView) view)) {
-                      if (setForTop) {
-                        drawTopDivider = false;
-                      }
-                      if (setForBottom) {
-                        drawBottomDivider = false;
-                      }
-                    } else {
-                      addScrollListener((ViewGroup) view, setForTop, setForBottom);
-                    }
-                    view.getViewTreeObserver().removeOnPreDrawListener(this);
-                  }
-                  return true;
-                }
-              });
-    } else if (view instanceof RecyclerView) {
-      boolean canScroll = canRecyclerViewScroll((RecyclerView) view);
-      if (setForTop) {
-        drawTopDivider = canScroll;
-      }
-      if (setForBottom) {
-        drawBottomDivider = canScroll;
-      }
-      if (canScroll) {
-        addScrollListener((ViewGroup) view, setForTop, setForBottom);
-      }
-    } else if (view instanceof ViewGroup) {
-      View topView = getTopView((ViewGroup) view);
-      setUpDividersVisibility(topView, setForTop, setForBottom);
-      View bottomView = getBottomView((ViewGroup) view);
-      if (bottomView != topView) {
-        setUpDividersVisibility(bottomView, false, true);
-      }
-    }
-  }
-
-  private void addScrollListener(
-      final ViewGroup vg, final boolean setForTop, final boolean setForBottom) {
-    if ((!setForBottom && topOnScrollChangedListener == null
-        || (setForBottom && bottomOnScrollChangedListener == null))) {
-      if (vg instanceof RecyclerView) {
-        RecyclerView.OnScrollListener scrollListener =
-            new RecyclerView.OnScrollListener() {
-              @Override
-              public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-                super.onScrolled(recyclerView, dx, dy);
-                boolean hasButtons = false;
-                for (MDButton button : buttons) {
-                  if (button != null && button.getVisibility() != View.GONE) {
-                    hasButtons = true;
-                    break;
-                  }
-                }
-                invalidateDividersForScrollingView(vg, setForTop, setForBottom, hasButtons);
-                invalidate();
-              }
-            };
-        ((RecyclerView) vg).addOnScrollListener(scrollListener);
-        scrollListener.onScrolled((RecyclerView) vg, 0, 0);
-      } else {
-        ViewTreeObserver.OnScrollChangedListener onScrollChangedListener =
-            new ViewTreeObserver.OnScrollChangedListener() {
-              @Override
-              public void onScrollChanged() {
-                boolean hasButtons = false;
-                for (MDButton button : buttons) {
-                  if (button != null && button.getVisibility() != View.GONE) {
-                    hasButtons = true;
-                    break;
-                  }
-                }
-                if (vg instanceof WebView) {
-                  invalidateDividersForWebView((WebView) vg, setForTop, setForBottom, hasButtons);
-                } else {
-                  invalidateDividersForScrollingView(vg, setForTop, setForBottom, hasButtons);
-                }
-                invalidate();
-              }
-            };
-        if (!setForBottom) {
-          topOnScrollChangedListener = onScrollChangedListener;
-          vg.getViewTreeObserver().addOnScrollChangedListener(topOnScrollChangedListener);
-        } else {
-          bottomOnScrollChangedListener = onScrollChangedListener;
-          vg.getViewTreeObserver().addOnScrollChangedListener(bottomOnScrollChangedListener);
-        }
-        onScrollChangedListener.onScrollChanged();
-      }
-    }
-  }
-
-  private void invalidateDividersForScrollingView(
-      ViewGroup view, final boolean setForTop, boolean setForBottom, boolean hasButtons) {
-    if (setForTop && view.getChildCount() > 0) {
-      drawTopDivider =
-          titleBar != null
-              && titleBar.getVisibility() != View.GONE
-              &&
-              // Not scrolled to the top.
-              view.getScrollY() + view.getPaddingTop() > view.getChildAt(0).getTop();
-    }
-    if (setForBottom && view.getChildCount() > 0) {
-      drawBottomDivider =
-          hasButtons
-              && view.getScrollY() + view.getHeight() - view.getPaddingBottom()
-                  < view.getChildAt(view.getChildCount() - 1).getBottom();
-    }
-  }
-
-  private void invalidateDividersForWebView(
-      WebView view, final boolean setForTop, boolean setForBottom, boolean hasButtons) {
-    if (setForTop) {
-      drawTopDivider =
-          titleBar != null
-              && titleBar.getVisibility() != View.GONE
-              &&
-              // Not scrolled to the top.
-              view.getScrollY() + view.getPaddingTop() > 0;
-    }
-    if (setForBottom) {
-      //noinspection deprecation
-      drawBottomDivider =
-          hasButtons
-              && view.getScrollY() + view.getMeasuredHeight() - view.getPaddingBottom()
-                  < view.getContentHeight() * view.getScale();
-    }
-  }
-}

+ 0 - 191
core/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java

@@ -1,191 +0,0 @@
-package com.afollestad.materialdialogs.internal;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.support.annotation.ColorInt;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v7.widget.AppCompatEditText;
-import android.util.Log;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.ProgressBar;
-import android.widget.RadioButton;
-import android.widget.SeekBar;
-import android.widget.TextView;
-import com.afollestad.materialdialogs.R;
-import com.afollestad.materialdialogs.util.DialogUtils;
-import java.lang.reflect.Field;
-
-/** Tints widgets */
-@SuppressLint("PrivateResource")
-public class MDTintHelper {
-
-  public static void setTint(RadioButton radioButton, ColorStateList colors) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-      radioButton.setButtonTintList(colors);
-    } else {
-      Drawable radioDrawable =
-          ContextCompat.getDrawable(radioButton.getContext(), R.drawable.abc_btn_radio_material);
-      Drawable d = DrawableCompat.wrap(radioDrawable);
-      DrawableCompat.setTintList(d, colors);
-      radioButton.setButtonDrawable(d);
-    }
-  }
-
-  public static void setTint(RadioButton radioButton, @ColorInt int color) {
-    final int disabledColor = DialogUtils.getDisabledColor(radioButton.getContext());
-    ColorStateList sl =
-        new ColorStateList(
-            new int[][] {
-              new int[] {android.R.attr.state_enabled, -android.R.attr.state_checked},
-              new int[] {android.R.attr.state_enabled, android.R.attr.state_checked},
-              new int[] {-android.R.attr.state_enabled, -android.R.attr.state_checked},
-              new int[] {-android.R.attr.state_enabled, android.R.attr.state_checked}
-            },
-            new int[] {
-              DialogUtils.resolveColor(radioButton.getContext(), R.attr.colorControlNormal),
-              color,
-              disabledColor,
-              disabledColor
-            });
-    setTint(radioButton, sl);
-  }
-
-  public static void setTint(CheckBox box, ColorStateList colors) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
-      box.setButtonTintList(colors);
-    } else {
-      Drawable checkDrawable =
-          ContextCompat.getDrawable(box.getContext(), R.drawable.abc_btn_check_material);
-      Drawable drawable = DrawableCompat.wrap(checkDrawable);
-      DrawableCompat.setTintList(drawable, colors);
-      box.setButtonDrawable(drawable);
-    }
-  }
-
-  public static void setTint(CheckBox box, @ColorInt int color) {
-    final int disabledColor = DialogUtils.getDisabledColor(box.getContext());
-    ColorStateList sl =
-        new ColorStateList(
-            new int[][] {
-              new int[] {android.R.attr.state_enabled, -android.R.attr.state_checked},
-              new int[] {android.R.attr.state_enabled, android.R.attr.state_checked},
-              new int[] {-android.R.attr.state_enabled, -android.R.attr.state_checked},
-              new int[] {-android.R.attr.state_enabled, android.R.attr.state_checked}
-            },
-            new int[] {
-              DialogUtils.resolveColor(box.getContext(), R.attr.colorControlNormal),
-              color,
-              disabledColor,
-              disabledColor
-            });
-    setTint(box, sl);
-  }
-
-  public static void setTint(SeekBar seekBar, @ColorInt int color) {
-    ColorStateList s1 = ColorStateList.valueOf(color);
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      seekBar.setThumbTintList(s1);
-      seekBar.setProgressTintList(s1);
-    } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) {
-      Drawable progressDrawable = DrawableCompat.wrap(seekBar.getProgressDrawable());
-      seekBar.setProgressDrawable(progressDrawable);
-      DrawableCompat.setTintList(progressDrawable, s1);
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-        Drawable thumbDrawable = DrawableCompat.wrap(seekBar.getThumb());
-        DrawableCompat.setTintList(thumbDrawable, s1);
-        seekBar.setThumb(thumbDrawable);
-      }
-    } else {
-      PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
-      if (seekBar.getIndeterminateDrawable() != null) {
-        seekBar.getIndeterminateDrawable().setColorFilter(color, mode);
-      }
-      if (seekBar.getProgressDrawable() != null) {
-        seekBar.getProgressDrawable().setColorFilter(color, mode);
-      }
-    }
-  }
-
-  public static void setTint(ProgressBar progressBar, @ColorInt int color) {
-    setTint(progressBar, color, false);
-  }
-
-  private static void setTint(
-      ProgressBar progressBar, @ColorInt int color, boolean skipIndeterminate) {
-    ColorStateList sl = ColorStateList.valueOf(color);
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      progressBar.setProgressTintList(sl);
-      progressBar.setSecondaryProgressTintList(sl);
-      if (!skipIndeterminate) {
-        progressBar.setIndeterminateTintList(sl);
-      }
-    } else {
-      PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
-      if (!skipIndeterminate && progressBar.getIndeterminateDrawable() != null) {
-        progressBar.getIndeterminateDrawable().setColorFilter(color, mode);
-      }
-      if (progressBar.getProgressDrawable() != null) {
-        progressBar.getProgressDrawable().setColorFilter(color, mode);
-      }
-    }
-  }
-
-  private static ColorStateList createEditTextColorStateList(Context context, @ColorInt int color) {
-    int[][] states = new int[3][];
-    int[] colors = new int[3];
-    int i = 0;
-    states[i] = new int[] {-android.R.attr.state_enabled};
-    colors[i] = DialogUtils.resolveColor(context, R.attr.colorControlNormal);
-    i++;
-    states[i] = new int[] {-android.R.attr.state_pressed, -android.R.attr.state_focused};
-    colors[i] = DialogUtils.resolveColor(context, R.attr.colorControlNormal);
-    i++;
-    states[i] = new int[] {};
-    colors[i] = color;
-    return new ColorStateList(states, colors);
-  }
-
-  @SuppressLint("RestrictedApi")
-  public static void setTint(EditText editText, @ColorInt int color) {
-    ColorStateList editTextColorStateList =
-        createEditTextColorStateList(editText.getContext(), color);
-    if (editText instanceof AppCompatEditText) {
-      //noinspection RestrictedApi
-      ((AppCompatEditText) editText).setSupportBackgroundTintList(editTextColorStateList);
-    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-      editText.setBackgroundTintList(editTextColorStateList);
-    }
-    setCursorTint(editText, color);
-  }
-
-  private static void setCursorTint(EditText editText, @ColorInt int color) {
-    try {
-      Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
-      fCursorDrawableRes.setAccessible(true);
-      int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
-      Field fEditor = TextView.class.getDeclaredField("mEditor");
-      fEditor.setAccessible(true);
-      Object editor = fEditor.get(editText);
-      Class<?> clazz = editor.getClass();
-      Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
-      fCursorDrawable.setAccessible(true);
-      Drawable[] drawables = new Drawable[2];
-      drawables[0] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes);
-      drawables[1] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes);
-      drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);
-      drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
-      fCursorDrawable.set(editor, drawables);
-    } catch (NoSuchFieldException e1) {
-      Log.d("MDTintHelper", "Device issue with cursor tinting: " + e1.getMessage());
-      e1.printStackTrace();
-    } catch (Exception e2) {
-      e2.printStackTrace();
-    }
-  }
-}

Некоторые файлы не были показаны из-за большого количества измененных файлов