1
0
Эх сурвалжийг харах

Merge branch 'master' of https://github.com/afollestad/material-dialogs

Kevin Barry 10 жил өмнө
parent
commit
ba015a5f82
26 өөрчлөгдсөн 587 нэмэгдсэн , 184 устгасан
  1. 166 54
      README.md
  2. 89 27
      library/src/main/java/com/afollestad/materialdialogs/DialogInit.java
  3. 1 0
      library/src/main/java/com/afollestad/materialdialogs/GravityEnum.java
  4. 65 33
      library/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java
  5. 10 7
      library/src/main/java/com/afollestad/materialdialogs/MaterialDialogAdapter.java
  6. 1 1
      library/src/main/java/com/afollestad/materialdialogs/ThemeSingleton.java
  7. 0 1
      library/src/main/java/com/afollestad/materialdialogs/base/DialogBase.java
  8. 5 8
      library/src/main/java/com/afollestad/materialdialogs/internal/MDButton.java
  9. 46 0
      library/src/main/java/com/afollestad/materialdialogs/internal/MDCheckBox.java
  10. 46 0
      library/src/main/java/com/afollestad/materialdialogs/internal/MDProgressBar.java
  11. 46 0
      library/src/main/java/com/afollestad/materialdialogs/internal/MDRadioButton.java
  12. 27 40
      library/src/main/java/com/afollestad/materialdialogs/internal/MDRootLayout.java
  13. 1 1
      library/src/main/java/com/afollestad/materialdialogs/prefs/MaterialEditTextPreference.java
  14. 1 1
      library/src/main/res/layout-ldrtl/md_listitem_multichoice.xml
  15. 1 1
      library/src/main/res/layout-ldrtl/md_listitem_singlechoice.xml
  16. 44 0
      library/src/main/res/layout/md_dialog_input.xml
  17. 1 2
      library/src/main/res/layout/md_dialog_progress.xml
  18. 1 1
      library/src/main/res/layout/md_listitem_multichoice.xml
  19. 1 1
      library/src/main/res/layout/md_listitem_singlechoice.xml
  20. 0 0
      library/src/main/res/layout/md_stub_inputpref.xml
  21. 1 1
      library/src/main/res/layout/md_stub_progress.xml
  22. 2 2
      library/src/main/res/layout/md_stub_progress_indeterminate.xml
  23. 1 1
      library/src/main/res/values/attrs.xml
  24. 21 2
      sample/src/main/java/com/afollestad/materialdialogssample/MainActivity.java
  25. 7 0
      sample/src/main/res/layout/activity_main.xml
  26. 3 0
      sample/src/main/res/values/strings.xml

+ 166 - 54
README.md

@@ -2,7 +2,7 @@
 
 ![Screenshots](https://raw.githubusercontent.com/afollestad/material-dialogs/master/art/screenshots.png)
 
-### Sample Project
+## Sample Project
 
 You can download the latest sample APK from this repo here: https://github.com/afollestad/material-dialogs/blob/master/sample/sample.apk
 
@@ -18,7 +18,7 @@ repository will allow GitHub to email you whenever I publish a release.
 
 ---
 
-### Gradle Dependency (jCenter)
+## Gradle Dependency (jCenter)
 
 Easily reference the library in your Android projects using this dependency in your module's `build.gradle` file:
 
@@ -32,17 +32,17 @@ dependencies {
 
 ---
 
-### What's New
+## What's New
 
 See the project's Releases page for a list of versions with their changelogs.
 
-[ ![View Releases](http://dabuttonfactory.com/b.png?t=View%20Releases&f=sans-serif-Bold&ts=14&tc=ffffff&c=5&bgt=unicolored&bgc=4B81BF&hp=20&vp=11) ](https://github.com/afollestad/material-dialogs/releases)
+###### [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
+## Basic Dialog
 
 First of all, note that `MaterialDialog` extends `DialogBase`, which extends `AlertDialog`. While
 a very small number of the stock methods are purposely deprecated and don't work, you have access
@@ -69,7 +69,7 @@ If the content is long enough, it will become scrollable and a divider will be d
 
 ---
 
-### Migration from AlertDialogs
+## Migration from AlertDialogs
 
 If you're migrating old dialogs you could use ```AlertDialogWrapper```. You need change imports and replace ```AlertDialog.Builder``` with ```AlertDialogWrapper.Builder```:
 
@@ -89,7 +89,7 @@ But it's highly recommended to use original ```MaterialDialog``` API for new usa
 
 ---
 
-### Displaying an Icon
+## Displaying an Icon
 
 MaterialDialog supports the display of an icon just like the stock AlertDialog; it will go to the left of the title.
 
@@ -107,7 +107,7 @@ You can limit the maximum size of the icon using the `limitIconToDefaultSize()`,
 
 ---
 
-### Stacked Action Buttons
+## 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 orientated.
@@ -125,7 +125,7 @@ You can also force the dialog to stack its buttons with the `forceStacking()` me
 
 ---
 
-### Neutral Action Button
+## 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.
@@ -142,7 +142,7 @@ new MaterialDialog.Builder(this)
 
 ---
 
-### Callbacks
+## Callbacks
 
 To know when the user selects an action button, you set a callback. To do this, use the `ButtonCallback`
 class and override its `onPositive()`, `onNegative()`, or `onNeutral()` methods as needed. The advantage
@@ -187,7 +187,7 @@ If `autoDismiss` is turned off, then you must manually dismiss the dialog in the
 
 ---
 
-### List Dialogs
+## List Dialogs
 
 Creating a list dialog only requires passing in an array of strings. The callback (`itemsCallback`) is
 also very simple.
@@ -210,7 +210,7 @@ below your list, however this is only useful in some specific cases.
 
 ---
 
-### Single Choice List Dialogs
+## 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
@@ -245,9 +245,21 @@ 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 an item.
 
+#### Coloring Radio Buttons (API 22+)
+
+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()`,
+ and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory.
+ 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`.
+
+Due to limitations, this only works correctly on API 22 (Android 5.1 Lollipop) and above.
+
 ---
 
-### Multi Choice List Dialogs
+## 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
@@ -283,9 +295,21 @@ 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 an item.
 
+#### Coloring Check Boxes (API 22+)
+
+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()`,
+ and `widgetColorAttr()` method. Their names and parameter annotations make them self explanatory. 
+ Note that by default, check boxes 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`.
+
+Due to limitations, this only works correctly on API 22 (Android 5.1 Lollipop) and above.
+
 ---
 
-### Custom List Dialogs
+## 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.
@@ -320,7 +344,7 @@ Note that you don't need to be using a custom adapter in order to access the `Li
 
 ---
 
-### Custom Views
+## Custom Views
 
 Custom views are very easy to implement.
 
@@ -342,7 +366,7 @@ including ListViews, RecyclerViews, WebViews, GridViews, etc. The sample project
 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
+#### 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
@@ -355,7 +379,7 @@ View view = dialog.getCustomView();
 
 ---
 
-### Typefaces
+## Typefaces
 
 By default, Material Dialogs will use the `Roboto Medium` font for the dialog title and action buttons,
 and `Roboto Regular` for content, list items, etc. This is done so using the font assets included in this library,
@@ -374,7 +398,7 @@ aren't ttf files, you can use the `typeface(Typeface, Typeface)` Builder method.
 
 ---
 
-### Getting and Setting Action Buttons
+## 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):
 
@@ -396,52 +420,109 @@ Setting an action button's text to null will cause it to be hidden. Do not manua
 
 ---
 
-### Theming
+## 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. Here's a basic example:
+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. 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)
-        .title(R.string.title)
-        .content(R.string.content)
-        .positiveText(R.string.positive)
-        .neutralText(R.string.neutral)
-        .negativeText(R.string.negative)
-        .positiveColorRes(R.color.material_red_500)
-        .neutralColorRes(R.color.material_red_500)
-        .negativeColorRes(R.color.material_red_500)
-        .progressColorRes(R.color.material_red_500)
-        .titleGravity(GravityEnum.CENTER_HORIZONTAL)
-        .contentGravity(GravityEnum.CENTER_HORIZONTAL)
-        .btnStackedGravity(GravityEnum.START)
-        .buttonsGravity(GravityEnum.END)
-        .itemsGravity(GravityEnum.END)
         .titleColorRes(R.color.material_red_500)
         .contentColorRes(Color.WHITE)
         .dividerColorRes(R.color.material_pink_500)
         .backgroundColorRes(R.color.material_blue_grey_800)
-        .btnSelectorStacked(R.drawable.custom_btn_selector_stacked)
+        .positiveColorRes(R.color.material_red_500)
+        .neutralColorRes(R.color.material_red_500)
+        .negativeColorRes(R.color.material_red_500)
+        .widgetColorRes(R.color.material_red_500)
+        .show();
+```
+
+The names are self explanatory for the most part. The `widgetColor` method is discussed in a few other
+sections of this tutorial, it applies to progress bars on all API levels, along check boxes and radio 
+buttons (on API 22 and above due to limitations). Also note that each of these methods have 3 variations 
+for setting a color directly, using color resources, and using color attributes.
+
+#### Selectors
+
+Theming selectors allows you to change colors for pressable things:
+
+```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)
-        .theme(Theme.DARK)
         .show();
 ```
 
-To see more colors that fit the Material design palette, see this page: http://www.google.com/design/spec/style/color.html#color-color-palette
+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.
 
 ***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_HORIZONTAL)
+        .contentGravity(GravityEnum.CENTER_HORIZONTAL)
+        .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). However, `buttonsGravity` 
+is a little less intuitive: think of it like it's changing the gravity of the neutral button. When you use START, 
+this is the normal configuration. The neutral button will be on the left (or right for RTL), the positive button 
+will be on the far right (or left for RTL), and the neutral button will be to the left of the positive button 
+(or right for RTL). Using END would result in the exact opposite. Using CENTER will put the neutral button
+in the center, the negative button on the left, and the positive button on the right (the negative and positive 
+positions switch for RTL).
+
+#### 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
+## Global Theming
 
-By default, the dialog inherits and extracts theme colors from other attributes and theme colors of the app
-or operating system. This behavior can be overridden in your Activity themes:
+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 these attributes:
 
 ```xml
 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
@@ -509,11 +590,11 @@ or operating system. This behavior can be overridden in your Activity themes:
     <item name="md_negative_color">#673AB7</item>
 
     <!--
-        By default, a progress dialog's progress indicator color is derived
-        from the colorAccent attribute of AppCompat or android:colorAccent
-        attribute of the Material theme.
+        By default, a progress dialog's progress bar, check boxes, and radio buttons 
+        have a color is derived from the colorAccent attribute of AppCompat or 
+        android:colorAccent attribute of the Material theme.
     -->
-    <item name="md_progress_color">#673AB7</item>
+    <item name="md_widget_color">#673AB7</item>
 
     <!--
         By default, the list item text color is black for the light
@@ -597,7 +678,7 @@ the color will override that behavior.
 
 ---
 
-### Show, Cancel, and Dismiss Callbacks
+## Show, Cancel, and Dismiss Callbacks
 
 You can directly setup show/cancel/dismiss listeners from the `Builder` rather than on the resulting
 `MaterialDialog` instance:
@@ -627,12 +708,41 @@ new MaterialDialog.Builder(this)
 
 ---
 
-### Progress Dialogs
+## 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)
+        .input(R.string.input_hint, R.string.input_prefill, new MaterialDialog.InputCallback() {
+            @Override
+            public void onInput(MaterialDialog dialog, CharSequence input) {
+                // Do something
+            }
+        }).show();
+```
+
+#### 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`.
+
+---
+
+## 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).
 
-###### Indeterminate Progress Dialogs
+#### Indeterminate Progress Dialogs
 
 This will display the classic progress dialog with a spinning circle, see the sample project to see it in action:
 
@@ -644,7 +754,7 @@ new MaterialDialog.Builder(this)
     .show();
 ```
 
-###### Determinate (Seek Bar) Progress Dialogs
+#### 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.
@@ -679,17 +789,19 @@ dialog.setContent(getString(R.string.done));
 
 See the sample project for this dialog in action, with the addition of threading.
 
-##### Coloring
+#### 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 indicator. The `Builder` class contains a `progressColor()`, `progressColorRes()`,
- and `progressColorAttr()` method. Their names and parameter annotations make them self explanatory.
+ 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_progress_color`.
+There's also a global theming attribute as shown in the Global Theming section of this README: `md_widget_color`.
 
 ---
 
-### Preference Dialogs
+## 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`,
@@ -698,7 +810,7 @@ dialogs. See the sample project for details.
 
 ---
 
-### Misc
+## 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:

+ 89 - 27
library/src/main/java/com/afollestad/materialdialogs/DialogInit.java

@@ -1,6 +1,7 @@
 package com.afollestad.materialdialogs;
 
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -12,15 +13,16 @@ import android.text.method.LinkMovementMethod;
 import android.view.ContextThemeWrapper;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.ListView;
-import android.widget.ProgressBar;
 import android.widget.ScrollView;
 import android.widget.TextView;
 
 import com.afollestad.materialdialogs.internal.MDButton;
+import com.afollestad.materialdialogs.internal.MDProgressBar;
 import com.afollestad.materialdialogs.util.DialogUtils;
 import com.afollestad.materialdialogs.util.TypefaceHelper;
 
@@ -54,10 +56,12 @@ class DialogInit {
             return R.layout.md_dialog_custom;
         } else if (builder.items != null && builder.items.length > 0 || builder.adapter != null) {
             return R.layout.md_dialog_list;
-        } else if (builder.mProgress > -2) {
+        } else if (builder.progress > -2) {
             return R.layout.md_dialog_progress;
-        } else if (builder.mIndeterminateProgress) {
+        } else if (builder.indeterminateProgress) {
             return R.layout.md_dialog_progress_indeterminate;
+        } else if (builder.inputCallback != null) {
+            return R.layout.md_dialog_input;
         } else {
             return R.layout.md_dialog_basic;
         }
@@ -85,7 +89,7 @@ class DialogInit {
         builder.positiveColor = DialogUtils.resolveColor(builder.context, R.attr.md_positive_color, builder.positiveColor);
         builder.neutralColor = DialogUtils.resolveColor(builder.context, R.attr.md_neutral_color, builder.neutralColor);
         builder.negativeColor = DialogUtils.resolveColor(builder.context, R.attr.md_negative_color, builder.negativeColor);
-        builder.progressColor = DialogUtils.resolveColor(builder.context, R.attr.md_progress_color, builder.progressColor);
+        builder.widgetColor = DialogUtils.resolveColor(builder.context, R.attr.md_widget_color, builder.widgetColor);
 
         // Retrieve default title/content colors
         if (!builder.titleColorSet) {
@@ -121,6 +125,9 @@ class DialogInit {
         dialog.neutralButton = (MDButton) dialog.view.findViewById(R.id.buttonDefaultNeutral);
         dialog.negativeButton = (MDButton) dialog.view.findViewById(R.id.buttonDefaultNegative);
 
+        if (builder.inputCallback != null && builder.positiveText == null)
+            builder.positiveText = builder.context.getString(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);
@@ -154,10 +161,8 @@ class DialogInit {
         }
 
         // Setup divider color in case content scrolls
-        if (builder.dividerColor == 0)
-            builder.dividerColor = DialogUtils.resolveColor(builder.context, R.attr.md_divider_color);
-        if (builder.dividerColor == 0)
-            builder.dividerColor = DialogUtils.resolveColor(dialog.getContext(), R.attr.md_divider);
+        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
@@ -207,6 +212,7 @@ class DialogInit {
         } else {
             textAllCaps = DialogUtils.resolveBoolean(builder.context, R.attr.textAllCaps, true);
         }
+
         if (dialog.positiveButton != null && builder.positiveText != null) {
             MDButton positiveTextView = dialog.positiveButton;
             dialog.setTypeface(positiveTextView, builder.mediumFont);
@@ -283,6 +289,10 @@ class DialogInit {
         // Setup progress dialog stuff if needed
         setupProgressDialog(dialog);
 
+        // Setup inputu dialog stuff if needed
+        setupInputDialog(dialog);
+
+        // Setup custom views
         if (builder.customView != null) {
             FrameLayout frame = (FrameLayout) dialog.view.findViewById(R.id.customViewFrame);
             dialog.customViewFrame = frame;
@@ -332,29 +342,19 @@ class DialogInit {
 
     private static void setupProgressDialog(final MaterialDialog dialog) {
         final MaterialDialog.Builder builder = dialog.mBuilder;
-        if (builder.mIndeterminateProgress || builder.mProgress > -2) {
-            dialog.mProgress = (ProgressBar) dialog.view.findViewById(android.R.id.progress);
-
-            // Color the progress bar
-            Drawable indDraw = dialog.mProgress.getIndeterminateDrawable();
-            if (indDraw != null) {
-                indDraw.setColorFilter(builder.progressColor, PorterDuff.Mode.SRC_ATOP);
-                dialog.mProgress.setIndeterminateDrawable(indDraw);
-            }
-            Drawable regDraw = dialog.mProgress.getProgressDrawable();
-            if (regDraw != null) {
-                regDraw.setColorFilter(builder.progressColor, PorterDuff.Mode.SRC_ATOP);
-                dialog.mProgress.setProgressDrawable(regDraw);
-            }
+        if (builder.indeterminateProgress || builder.progress > -2) {
+            dialog.mProgress = (MDProgressBar) dialog.view.findViewById(android.R.id.progress);
+            if (dialog.mProgress == null) return;
+            dialog.mProgress.setColorFilter(builder.widgetColor);
 
-            if (!builder.mIndeterminateProgress) {
+            if (!builder.indeterminateProgress) {
                 dialog.mProgress.setProgress(0);
-                dialog.mProgress.setMax(builder.mProgressMax);
+                dialog.mProgress.setMax(builder.progressMax);
                 dialog.mProgressLabel = (TextView) dialog.view.findViewById(R.id.label);
                 dialog.mProgressMinMax = (TextView) dialog.view.findViewById(R.id.minMax);
-                if (builder.mShowMinMax) {
+                if (builder.showMinMax) {
                     dialog.mProgressMinMax.setVisibility(View.VISIBLE);
-                    dialog.mProgressMinMax.setText("0/" + builder.mProgressMax);
+                    dialog.mProgressMinMax.setText("0/" + builder.progressMax);
                     ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) dialog.mProgress.getLayoutParams();
                     lp.leftMargin = 0;
                     lp.rightMargin = 0;
@@ -363,10 +363,72 @@ class DialogInit {
                 }
                 dialog.mProgressLabel.setText("0%");
             }
-
         }
     }
 
+    private static void setupInputDialog(final MaterialDialog dialog) {
+        final MaterialDialog.Builder builder = dialog.mBuilder;
+        dialog.input = (EditText) dialog.view.findViewById(android.R.id.input);
+        if (dialog.input == null) return;
+        if (builder.inputPrefill != null)
+            dialog.input.append(builder.inputPrefill);
+        dialog.input.setHint(builder.inputHint);
+        dialog.input.setSingleLine();
+
+        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
+            @Override
+            public void onShow(DialogInterface di) {
+                final MaterialDialog dialog = (MaterialDialog) di;
+                if (dialog.getInputEditText() == null) return;
+                dialog.getInputEditText().post(new Runnable() {
+                    @Override
+                    public void run() {
+                        dialog.getInputEditText().requestFocus();
+                        InputMethodManager imm = (InputMethodManager) builder.context.getSystemService(Context.INPUT_METHOD_SERVICE);
+                        if (imm != null)
+                            imm.showSoftInput(dialog.getInputEditText(), InputMethodManager.SHOW_IMPLICIT);
+                    }
+                });
+            }
+        });
+        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+            @Override
+            public void onCancel(DialogInterface di) {
+                final MaterialDialog dialog = (MaterialDialog) di;
+                if (dialog.getInputEditText() == null) return;
+                dialog.getInputEditText().post(new Runnable() {
+                    @Override
+                    public void run() {
+                        dialog.getInputEditText().requestFocus();
+                        InputMethodManager imm = (InputMethodManager) builder.context.getSystemService(Context.INPUT_METHOD_SERVICE);
+                        imm.hideSoftInputFromWindow(dialog.getInputEditText().getWindowToken(), 0);
+                    }
+                });
+            }
+        });
+        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+            @Override
+            public void onDismiss(DialogInterface di) {
+                final MaterialDialog dialog = (MaterialDialog) di;
+                if (dialog.getInputEditText() == null) return;
+                dialog.getInputEditText().post(new Runnable() {
+                    @Override
+                    public void run() {
+                        dialog.getInputEditText().requestFocus();
+                        InputMethodManager imm = (InputMethodManager) builder.context.getSystemService(Context.INPUT_METHOD_SERVICE);
+                        if (imm != null)
+                            imm.hideSoftInputFromWindow(dialog.getInputEditText().getWindowToken(), 0);
+                    }
+                });
+            }
+        });
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+            dialog.input.setBackgroundTintList(ColorStateList.valueOf(builder.widgetColor));
+        else if (dialog.input.getBackground() != null)
+            dialog.input.getBackground().setColorFilter(builder.widgetColor, PorterDuff.Mode.SRC_IN);
+    }
+
     private static ColorStateList getActionTextStateList(Context context, int newPrimaryColor) {
         final int fallBackButtonColor = DialogUtils.resolveColor(context, android.R.attr.textColorPrimary);
         if (newPrimaryColor == 0) newPrimaryColor = fallBackButtonColor;

+ 1 - 0
library/src/main/java/com/afollestad/materialdialogs/GravityEnum.java

@@ -8,6 +8,7 @@ public enum GravityEnum {
     START, CENTER, END;
 
     private static final boolean HAS_RTL = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
+
     public int getGravityInt() {
         switch (this) {
             case START:

+ 65 - 33
library/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java

@@ -27,16 +27,17 @@ import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.CheckBox;
+import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
 import android.widget.ListView;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.afollestad.materialdialogs.base.DialogBase;
 import com.afollestad.materialdialogs.internal.MDButton;
+import com.afollestad.materialdialogs.internal.MDProgressBar;
 import com.afollestad.materialdialogs.internal.MDRootLayout;
 import com.afollestad.materialdialogs.util.DialogUtils;
 import com.afollestad.materialdialogs.util.TypefaceHelper;
@@ -59,10 +60,11 @@ public class MaterialDialog extends DialogBase implements
     protected TextView title;
     protected View titleFrame;
     protected FrameLayout customViewFrame;
-    protected ProgressBar mProgress;
+    protected MDProgressBar mProgress;
     protected TextView mProgressLabel;
     protected TextView mProgressMinMax;
     protected TextView content;
+    protected EditText input;
 
     protected MDButton positiveButton;
     protected MDButton neutralButton;
@@ -299,6 +301,8 @@ public class MaterialDialog extends DialogBase implements
                     sendSingleChoiceCallback(v);
                 if (mBuilder.listCallbackMultiChoice != null)
                     sendMultichoiceCallback();
+                if (mBuilder.inputCallback != null && input != null)
+                    mBuilder.inputCallback.onInput(this, input.getText());
                 if (mBuilder.autoDismiss) dismiss();
                 break;
             }
@@ -337,7 +341,7 @@ public class MaterialDialog extends DialogBase implements
         protected CharSequence neutralText;
         protected CharSequence negativeText;
         protected View customView;
-        protected int progressColor;
+        protected int widgetColor;
         protected int positiveColor;
         protected int negativeColor;
         protected int neutralColor;
@@ -370,10 +374,13 @@ public class MaterialDialog extends DialogBase implements
         protected int dividerColor;
         protected int backgroundColor;
         protected int itemColor;
-        protected boolean mIndeterminateProgress;
-        protected boolean mShowMinMax;
-        protected int mProgress = -2;
-        protected int mProgressMax = 0;
+        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 titleColorSet = false;
         protected boolean contentColorSet = false;
@@ -397,17 +404,21 @@ public class MaterialDialog extends DialogBase implements
             // Retrieve default accent colors, which are used on the action buttons and progress bars
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                 final int fallback = DialogUtils.resolveColor(context, R.attr.colorAccent, materialBlue);
-                this.progressColor = DialogUtils.resolveColor(context, android.R.attr.colorAccent, fallback);
-                this.positiveColor = this.progressColor;
-                this.negativeColor = this.progressColor;
-                this.neutralColor = this.progressColor;
+                this.widgetColor = DialogUtils.resolveColor(context, android.R.attr.colorAccent, fallback);
+                this.positiveColor = this.widgetColor;
+                this.negativeColor = this.widgetColor;
+                this.neutralColor = this.widgetColor;
             } else {
-                this.progressColor = DialogUtils.resolveColor(context, R.attr.colorAccent, materialBlue);
-                this.positiveColor = this.progressColor;
-                this.negativeColor = this.progressColor;
-                this.neutralColor = this.progressColor;
+                this.widgetColor = DialogUtils.resolveColor(context, R.attr.colorAccent, materialBlue);
+                this.positiveColor = this.widgetColor;
+                this.negativeColor = this.widgetColor;
+                this.neutralColor = this.widgetColor;
             }
 
+            // 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();
 
@@ -451,8 +462,8 @@ public class MaterialDialog extends DialogBase implements
                 this.btnSelectorNeutral = s.btnSelectorNeutral;
             if (s.btnSelectorNegative != 0)
                 this.btnSelectorNegative = s.btnSelectorNegative;
-            if (s.progressColor != 0)
-                this.progressColor = s.progressColor;
+            if (s.widgetColor != 0)
+                this.widgetColor = s.widgetColor;
             this.titleGravity = s.titleGravity;
             this.contentGravity = s.contentGravity;
             this.btnStackedGravity = s.btnStackedGravity;
@@ -817,12 +828,12 @@ public class MaterialDialog extends DialogBase implements
          */
         public Builder progress(boolean indeterminate, int max) {
             if (indeterminate) {
-                this.mIndeterminateProgress = true;
-                this.mProgress = -2;
+                this.indeterminateProgress = true;
+                this.progress = -2;
             } else {
-                this.mIndeterminateProgress = false;
-                this.mProgress = -1;
-                this.mProgressMax = max;
+                this.indeterminateProgress = false;
+                this.progress = -1;
+                this.progressMax = max;
             }
             return this;
         }
@@ -836,21 +847,21 @@ public class MaterialDialog extends DialogBase implements
          * @return An instance of the Builder so calls can be chained.
          */
         public Builder progress(boolean indeterminate, int max, boolean showMinMax) {
-            this.mShowMinMax = showMinMax;
+            this.showMinMax = showMinMax;
             return progress(indeterminate, max);
         }
 
-        public Builder progressColor(int color) {
-            this.progressColor = color;
+        public Builder widgetColor(int color) {
+            this.widgetColor = color;
             return this;
         }
 
-        public Builder progressColorRes(@ColorRes int colorRes) {
-            return progressColor(this.context.getResources().getColor(colorRes));
+        public Builder widgetColorRes(@ColorRes int colorRes) {
+            return widgetColor(this.context.getResources().getColor(colorRes));
         }
 
-        public Builder progressColorAttr(@AttrRes int colorAttr) {
-            return progressColorRes(DialogUtils.resolveColor(this.context, colorAttr));
+        public Builder widgetColorAttr(@AttrRes int colorAttr) {
+            return widgetColorRes(DialogUtils.resolveColor(this.context, colorAttr));
         }
 
         public Builder dividerColor(int color) {
@@ -962,6 +973,17 @@ public class MaterialDialog extends DialogBase implements
             return this;
         }
 
+        public Builder input(CharSequence hint, CharSequence prefill, @NonNull InputCallback callback) {
+            this.inputCallback = callback;
+            this.inputHint = hint;
+            this.inputPrefill = prefill;
+            return this;
+        }
+
+        public Builder input(@StringRes int hint, @StringRes int prefill, @NonNull InputCallback callback) {
+            return input(hint == 0 ? null : context.getString(hint), prefill == 0 ? null : context.getString(prefill), callback);
+        }
+
         public MaterialDialog build() {
             return new MaterialDialog(this);
         }
@@ -1037,6 +1059,11 @@ public class MaterialDialog extends DialogBase implements
         return listView;
     }
 
+    @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.
@@ -1185,7 +1212,7 @@ public class MaterialDialog extends DialogBase implements
     }
 
     public final void incrementProgress(int by) {
-        if (mBuilder.mProgress <= -2)
+        if (mBuilder.progress <= -2)
             throw new IllegalStateException("Cannot use incrementProgress() on this dialog.");
         setProgress(getCurrentProgress() + by);
     }
@@ -1193,7 +1220,7 @@ public class MaterialDialog extends DialogBase implements
     public final void setProgress(int progress) {
         if (Looper.myLooper() != Looper.getMainLooper())
             throw new IllegalStateException("You can only set the dialog's progress from the UI thread.");
-        else if (mBuilder.mProgress <= -2)
+        else if (mBuilder.progress <= -2)
             throw new IllegalStateException("Cannot use setProgress() on this dialog.");
         mProgress.setProgress(progress);
         int percentage = (int) (((float) getCurrentProgress() / (float) getMaxProgress()) * 100f);
@@ -1205,13 +1232,13 @@ public class MaterialDialog extends DialogBase implements
     public final void setMaxProgress(int max) {
         if (Looper.myLooper() != Looper.getMainLooper())
             throw new IllegalStateException("You can only set the dialog's progress from the UI thread.");
-        else if (mBuilder.mProgress <= -2)
+        else if (mBuilder.progress <= -2)
             throw new IllegalStateException("Cannot use setMaxProgress() on this dialog.");
         mProgress.setMax(max);
     }
 
     public final boolean isIndeterminateProgress() {
-        return mBuilder.mIndeterminateProgress;
+        return mBuilder.indeterminateProgress;
     }
 
     public final int getMaxProgress() {
@@ -1380,4 +1407,9 @@ public class MaterialDialog extends DialogBase implements
             return super.toString();
         }
     }
+
+    public interface InputCallback {
+
+        void onInput(MaterialDialog dialog, CharSequence input);
+    }
 }

+ 10 - 7
library/src/main/java/com/afollestad/materialdialogs/MaterialDialogAdapter.java

@@ -8,13 +8,12 @@ import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.LinearLayout;
-import android.widget.RadioButton;
 import android.widget.TextView;
 
-import com.afollestad.materialdialogs.util.DialogUtils;
+import com.afollestad.materialdialogs.internal.MDCheckBox;
+import com.afollestad.materialdialogs.internal.MDRadioButton;
 
 class MaterialDialogAdapter extends ArrayAdapter<CharSequence> {
 
@@ -45,14 +44,18 @@ class MaterialDialogAdapter extends ArrayAdapter<CharSequence> {
         switch (dialog.listType) {
             case SINGLE: {
                 @SuppressLint("CutPasteId")
-                RadioButton radio = (RadioButton) view.findViewById(R.id.control);
-                radio.setChecked(dialog.mBuilder.selectedIndex == index);
+                MDRadioButton radio = (MDRadioButton) view.findViewById(R.id.control);
+                boolean selected = dialog.mBuilder.selectedIndex == index;
+                radio.setColorFilter(dialog.mBuilder.widgetColor);
+                radio.setChecked(selected);
                 break;
             }
             case MULTI: {
                 @SuppressLint("CutPasteId")
-                CheckBox checkbox = (CheckBox) view.findViewById(R.id.control);
-                checkbox.setChecked(dialog.selectedIndicesList.contains(index));
+                MDCheckBox checkbox = (MDCheckBox) view.findViewById(R.id.control);
+                boolean selected = dialog.selectedIndicesList.contains(index);
+                checkbox.setColorFilter(dialog.mBuilder.widgetColor);
+                checkbox.setChecked(selected);
                 break;
             }
         }

+ 1 - 1
library/src/main/java/com/afollestad/materialdialogs/ThemeSingleton.java

@@ -26,7 +26,7 @@ public class ThemeSingleton {
     public int positiveColor = 0;
     public int neutralColor = 0;
     public int negativeColor = 0;
-    public int progressColor = 0;
+    public int widgetColor = 0;
     public int itemColor = 0;
     public Drawable icon = null;
     public int backgroundColor = 0;

+ 0 - 1
library/src/main/java/com/afollestad/materialdialogs/base/DialogBase.java

@@ -95,5 +95,4 @@ public class DialogBase extends AlertDialog implements DialogInterface.OnShowLis
         if (mShowListener != null)
             mShowListener.onShow(dialog);
     }
-
 }

+ 5 - 8
library/src/main/java/com/afollestad/materialdialogs/internal/MDButton.java

@@ -65,7 +65,6 @@ public class MDButton extends TextView {
             if (stacked) {
                 setPadding(mStackedEndPadding, getPaddingTop(), mStackedEndPadding, getPaddingBottom());
             } /* Else the padding was properly reset by the drawable */
-
         }
     }
 
@@ -76,25 +75,23 @@ public class MDButton extends TextView {
     public void setStackedSelector(Drawable d) {
         mStackedBackground = d;
         if (mStacked)
-            setStacked(mStacked, true);
+            setStacked(true, true);
     }
 
     public void setDefaultSelector(Drawable d) {
         mDefaultBackground = d;
         if (!mStacked)
-            setStacked(mStacked, true);
+            setStacked(true, true);
     }
 
     public void setAllCapsCompat(boolean allCaps) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
             setAllCaps(allCaps);
         } else {
-            if (allCaps) {
+            if (allCaps)
                 setTransformationMethod(new AllCapsTransformationMethod(getContext()));
-            } else {
+            else
                 setTransformationMethod(null);
-            }
         }
     }
-
-}
+}

+ 46 - 0
library/src/main/java/com/afollestad/materialdialogs/internal/MDCheckBox.java

@@ -0,0 +1,46 @@
+package com.afollestad.materialdialogs.internal;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.widget.CheckBox;
+
+import com.afollestad.materialdialogs.util.DialogUtils;
+
+/**
+ * @author Aidan Follestad (afollestad)
+ */
+public class MDCheckBox extends CheckBox {
+
+    public MDCheckBox(Context context) {
+        super(context);
+    }
+
+    public MDCheckBox(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public MDCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public MDCheckBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public void setColorFilter(int color) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
+            ColorStateList sl = new ColorStateList(new int[][]{
+                    new int[]{-android.R.attr.state_checked},
+                    new int[]{android.R.attr.state_checked}
+            }, new int[]{
+                    DialogUtils.resolveColor(getContext(), android.R.attr.textColorSecondary),
+                    color
+            });
+            setButtonTintList(sl);
+        }
+    }
+}

+ 46 - 0
library/src/main/java/com/afollestad/materialdialogs/internal/MDProgressBar.java

@@ -0,0 +1,46 @@
+package com.afollestad.materialdialogs.internal;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.widget.ProgressBar;
+
+/**
+ * @author Aidan Follestad (afollestad)
+ */
+public class MDProgressBar extends ProgressBar {
+
+    public MDProgressBar(Context context) {
+        super(context);
+    }
+
+    public MDProgressBar(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public MDProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public MDProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public void setColorFilter(int color) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            ColorStateList stateList = ColorStateList.valueOf(color);
+            setProgressTintList(stateList);
+            setSecondaryProgressTintList(stateList);
+            setIndeterminateTintList(stateList);
+        } else {
+            if (getIndeterminateDrawable() != null)
+                getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+            if (getProgressDrawable() != null)
+                getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+        }
+    }
+}

+ 46 - 0
library/src/main/java/com/afollestad/materialdialogs/internal/MDRadioButton.java

@@ -0,0 +1,46 @@
+package com.afollestad.materialdialogs.internal;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.widget.RadioButton;
+
+import com.afollestad.materialdialogs.util.DialogUtils;
+
+/**
+ * @author Aidan Follestad (afollestad)
+ */
+public class MDRadioButton extends RadioButton {
+
+    public MDRadioButton(Context context) {
+        super(context);
+    }
+
+    public MDRadioButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public MDRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public MDRadioButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public void setColorFilter(int color) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
+            ColorStateList sl = new ColorStateList(new int[][]{
+                    new int[]{-android.R.attr.state_checked},
+                    new int[]{android.R.attr.state_checked}
+            }, new int[]{
+                    DialogUtils.resolveColor(getContext(), android.R.attr.textColorSecondary),
+                    color
+            });
+            setButtonTintList(sl);
+        }
+    }
+}

+ 27 - 40
library/src/main/java/com/afollestad/materialdialogs/internal/MDRootLayout.java

@@ -21,12 +21,12 @@ import com.afollestad.materialdialogs.util.RecyclerUtil;
 
 /**
  * @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)
+ *         <p/>
+ *         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 String TAG = "MD.RootView";
@@ -94,7 +94,6 @@ public class MDRootLayout extends ViewGroup {
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
-
         for (int i = 0; i < getChildCount(); i++) {
             View v = getChildAt(i);
             if (v.getId() == R.id.titleFrame) {
@@ -122,8 +121,7 @@ public class MDRootLayout extends ViewGroup {
         final boolean stacked;
         if (!mForceStack) {
             int buttonsWidth = 0;
-            for (int i = 0; i < mButtons.length; i++) {
-                MDButton button = mButtons[i];
+            for (MDButton button : mButtons) {
                 if (button != null && button.getVisibility() != View.GONE) {
                     button.setStacked(false, false);
                     measureChild(button, widthMeasureSpec, heightMeasureSpec);
@@ -137,14 +135,13 @@ public class MDRootLayout extends ViewGroup {
             final int buttonFrameWidth = width - 2 * buttonBarPadding;
             stacked = buttonsWidth > buttonFrameWidth;
         } else {
-            stacked = mForceStack;
+            stacked = true;
         }
 
         int stackedHeight = 0;
         mIsStacked = stacked;
         if (stacked) {
-            for (int i = 0; i < mButtons.length; i++) {
-                MDButton button = mButtons[i];
+            for (MDButton button : mButtons) {
                 if (button != null && button.getVisibility() != View.GONE) {
                     button.setStacked(true, false);
                     measureChild(button, widthMeasureSpec, heightMeasureSpec);
@@ -160,8 +157,8 @@ public class MDRootLayout extends ViewGroup {
         if (hasButtons) {
             if (mIsStacked) {
                 availableHeight -= stackedHeight;
-                fullPadding += 2*mButtonPaddingFull;
-                minPadding += 2*mButtonPaddingFull;
+                fullPadding += 2 * mButtonPaddingFull;
+                minPadding += 2 * mButtonPaddingFull;
             } else {
                 availableHeight -= mButtonBarHeight;
                 fullPadding += 2 * mButtonPaddingFull;
@@ -169,7 +166,7 @@ public class MDRootLayout extends ViewGroup {
             }
         } else {
             /* Content has 8dp, we add 16dp and get 24dp, the frame margin */
-            fullPadding += 2*mButtonPaddingFull;
+            fullPadding += 2 * mButtonPaddingFull;
         }
 
         if (mTitleBar != null && mTitleBar.getVisibility() != View.GONE) {
@@ -190,9 +187,9 @@ public class MDRootLayout extends ViewGroup {
             } else {
                 mUseFullPadding = false;
                 availableHeight = 0;
-                mDrawTopDivider =  mTitleBar != null && mTitleBar.getVisibility() != View.GONE &&
+                mDrawTopDivider = mTitleBar != null && mTitleBar.getVisibility() != View.GONE &&
                         canViewOrChildScroll(mContent, false);
-                mDrawBottomDivider =  hasButtons &&
+                mDrawBottomDivider = hasButtons &&
                         canViewOrChildScroll(mContent, true);
             }
 
@@ -228,24 +225,22 @@ public class MDRootLayout extends ViewGroup {
             t += mNoTitlePaddingFull;
         }
 
-        if (mContent != null && mContent.getVisibility() != View.GONE) {
+        if (mContent != null && mContent.getVisibility() != View.GONE)
             mContent.layout(l, t, r, t + mContent.getMeasuredHeight());
-        }
 
         if (mIsStacked) {
             b -= mButtonPaddingFull;
-            for (int i = 0; i < mButtons.length; i++) {
-                if (mButtons[i] != null && mButtons[i].getVisibility() != View.GONE) {
-                    mButtons[i].layout(l, b - mButtons[i].getMeasuredHeight(), r, b);
-                    b -= mButtons[i].getMeasuredHeight();
+            for (MDButton mButton : mButtons) {
+                if (mButton != null && mButton.getVisibility() != View.GONE) {
+                    mButton.layout(l, b - mButton.getMeasuredHeight(), r, b);
+                    b -= mButton.getMeasuredHeight();
                 }
             }
         } else {
             int barTop;
             int barBottom = b;
-            if (mUseFullPadding) {
+            if (mUseFullPadding)
                 barBottom -= mButtonPaddingFull;
-            }
             barTop = barBottom - mButtonBarHeight;
             /* START:
                Neutral   Negative  Positive
@@ -266,7 +261,6 @@ public class MDRootLayout extends ViewGroup {
 
             if (mButtons[INDEX_POSITIVE] != null && mButtons[INDEX_POSITIVE].getVisibility() != View.GONE) {
                 int bl, br;
-
                 if (mButtonGravity == GravityEnum.END) {
                     bl = l + offset;
                     br = bl + mButtons[INDEX_POSITIVE].getMeasuredWidth();
@@ -275,16 +269,12 @@ public class MDRootLayout extends ViewGroup {
                     bl = br - mButtons[INDEX_POSITIVE].getMeasuredWidth();
                     neutralRight = bl;
                 }
-
                 mButtons[INDEX_POSITIVE].layout(bl, barTop, br, barBottom);
-
                 offset += mButtons[INDEX_POSITIVE].getMeasuredWidth();
             }
 
             if (mButtons[INDEX_NEGATIVE] != null && mButtons[INDEX_NEGATIVE].getVisibility() != View.GONE) {
-
                 int bl, br;
-
                 if (mButtonGravity == GravityEnum.END) {
                     bl = l + offset;
                     br = bl + mButtons[INDEX_NEGATIVE].getMeasuredWidth();
@@ -296,7 +286,6 @@ public class MDRootLayout extends ViewGroup {
                     br = bl + mButtons[INDEX_NEGATIVE].getMeasuredWidth();
                     neutralLeft = br;
                 }
-
                 mButtons[INDEX_NEGATIVE].layout(bl, barTop, br, barBottom);
             }
 
@@ -313,8 +302,8 @@ public class MDRootLayout extends ViewGroup {
                         neutralLeft = neutralRight - mButtons[INDEX_NEUTRAL].getMeasuredWidth();
                     } else if (neutralRight == -1 && neutralLeft != -1) {
                         neutralRight = neutralLeft + mButtons[INDEX_NEUTRAL].getMeasuredWidth();
-                    } else if (neutralRight == -1 && neutralLeft == -1) {
-                        neutralLeft = (r - l)/2 - mButtons[INDEX_NEUTRAL].getMeasuredWidth()/2;
+                    } else if (neutralRight == -1) {
+                        neutralLeft = (r - l) / 2 - mButtons[INDEX_NEUTRAL].getMeasuredWidth() / 2;
                         neutralRight = neutralLeft + mButtons[INDEX_NEUTRAL].getMeasuredWidth();
                     }
                     bl = neutralLeft;
@@ -341,9 +330,9 @@ public class MDRootLayout extends ViewGroup {
     }
 
     public void setButtonStackedGravity(GravityEnum gravity) {
-        for (int i = 0; i < mButtons.length; i++) {
-            if (mButtons[i] != null)
-                mButtons[i].setStackedGravity(gravity);
+        for (MDButton mButton : mButtons) {
+            if (mButton != null)
+                mButton.setStackedGravity(gravity);
         }
     }
 
@@ -393,7 +382,6 @@ public class MDRootLayout extends ViewGroup {
             /* 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();
@@ -411,8 +399,7 @@ public class MDRootLayout extends ViewGroup {
      */
     @Nullable
     private static View getBottomView(ViewGroup viewGroup) {
-        if (viewGroup == null)
-            return null;
+        if (viewGroup == null) return null;
         View bottomView = null;
         for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
             View child = viewGroup.getChildAt(i);
@@ -438,4 +425,4 @@ public class MDRootLayout extends ViewGroup {
         }
         return topView;
     }
-}
+}

+ 1 - 1
library/src/main/java/com/afollestad/materialdialogs/prefs/MaterialEditTextPreference.java

@@ -74,7 +74,7 @@ public class MaterialEditTextPreference extends EditTextPreference {
                 .dismissListener(this)
                 .content(getDialogMessage());
 
-        View layout = LayoutInflater.from(getContext()).inflate(R.layout.md_stub_input, null);
+        View layout = LayoutInflater.from(getContext()).inflate(R.layout.md_stub_inputpref, null);
         onBindDialogView(layout);
 
         if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP)

+ 1 - 1
library/src/main/res/layout-ldrtl/md_listitem_multichoice.xml

@@ -22,7 +22,7 @@
         android:paddingEnd="@dimen/md_listitem_control_margin"
         tools:ignore="RtlSymmetry" />
 
-    <CheckBox
+    <com.afollestad.materialdialogs.internal.MDCheckBox
         android:id="@+id/control"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"

+ 1 - 1
library/src/main/res/layout-ldrtl/md_listitem_singlechoice.xml

@@ -22,7 +22,7 @@
         android:paddingEnd="@dimen/md_listitem_control_margin"
         tools:ignore="RtlSymmetry" />
 
-    <RadioButton
+    <com.afollestad.materialdialogs.internal.MDRadioButton
         android:id="@+id/control"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"

+ 44 - 0
library/src/main/res/layout/md_dialog_input.xml

@@ -0,0 +1,44 @@
+<com.afollestad.materialdialogs.internal.MDRootLayout xmlns:tools="http://schemas.android.com/tools"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <include layout="@layout/md_stub_titleframe" />
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:paddingLeft="@dimen/md_dialog_frame_margin"
+        android:paddingRight="@dimen/md_dialog_frame_margin"
+        android:paddingTop="@dimen/md_content_padding_top"
+        android:paddingBottom="@dimen/md_content_padding_bottom">
+
+        <TextView
+            android:id="@+id/content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:fontFamily="sans-serif"
+            android:textSize="@dimen/md_content_textsize"
+            android:layout_marginTop="4dp"
+            android:layout_marginBottom="8dp"
+            android:layout_marginLeft="2dp"
+            android:layout_marginRight="2dp"
+            tools:text="Message"
+            android:layout_gravity="center_horizontal"
+            tools:ignore="UnusedAttribute" />
+
+        <EditText
+            android:id="@android:id/input"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="@dimen/md_content_textsize"
+            tools:ignore="TextFields" />
+
+    </LinearLayout>
+
+    <include layout="@layout/md_stub_actionbuttons" />
+
+</com.afollestad.materialdialogs.internal.MDRootLayout>

+ 1 - 2
library/src/main/res/layout/md_dialog_progress.xml

@@ -14,8 +14,7 @@
         android:paddingLeft="@dimen/md_dialog_frame_margin"
         android:paddingRight="@dimen/md_dialog_frame_margin"
         android:paddingTop="@dimen/md_content_padding_top"
-        android:paddingBottom="@dimen/md_content_padding_bottom"
-        >
+        android:paddingBottom="@dimen/md_content_padding_bottom">
 
         <include layout="@layout/md_stub_progress" />
 

+ 1 - 1
library/src/main/res/layout/md_listitem_multichoice.xml

@@ -10,7 +10,7 @@
     android:paddingRight="@dimen/md_dialog_frame_margin"
     android:paddingEnd="@dimen/md_dialog_frame_margin">
 
-    <CheckBox
+    <com.afollestad.materialdialogs.internal.MDCheckBox
         android:id="@+id/control"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"

+ 1 - 1
library/src/main/res/layout/md_listitem_singlechoice.xml

@@ -10,7 +10,7 @@
     android:paddingRight="@dimen/md_dialog_frame_margin"
     android:paddingEnd="@dimen/md_dialog_frame_margin">
 
-    <RadioButton
+    <com.afollestad.materialdialogs.internal.MDRadioButton
         android:id="@+id/control"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"

+ 0 - 0
library/src/main/res/layout/md_stub_input.xml → library/src/main/res/layout/md_stub_inputpref.xml


+ 1 - 1
library/src/main/res/layout/md_stub_progress.xml

@@ -34,7 +34,7 @@
             android:layout_alignParentStart="true"
             android:layout_centerVertical="true" />
 
-        <ProgressBar
+        <com.afollestad.materialdialogs.internal.MDProgressBar
             android:id="@android:id/progress"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"

+ 2 - 2
library/src/main/res/layout/md_stub_progress_indeterminate.xml

@@ -10,7 +10,7 @@
     android:paddingBottom="@dimen/md_content_padding_top"
     android:gravity="end|center_vertical">
 
-    <ProgressBar
+    <com.afollestad.materialdialogs.internal.MDProgressBar
         android:id="@android:id/progress"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />
@@ -22,7 +22,7 @@
         android:fontFamily="sans-serif"
         android:textSize="16sp"
         tools:text="Message"
-        tools:ignore="UnusedAttribute"
+        tools:ignore="NewApi,RtlSymmetry,UnusedAttribute"
         android:paddingLeft="16dp"
         android:paddingStart="16dp"
         android:gravity="start"

+ 1 - 1
library/src/main/res/values/attrs.xml

@@ -18,7 +18,7 @@
     <attr name="md_positive_color" format="color" />
     <attr name="md_neutral_color" format="color" />
     <attr name="md_negative_color" format="color" />
-    <attr name="md_progress_color" format="color" />
+    <attr name="md_widget_color" format="color" />
 
     <attr name="md_item_color" format="color" />
     <attr name="md_divider_color" format="color" />

+ 21 - 2
sample/src/main/java/com/afollestad/materialdialogssample/MainActivity.java

@@ -196,6 +196,13 @@ public class MainActivity extends ActionBarActivity implements
             }
         });
 
+        findViewById(R.id.input).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showInputDialog();
+            }
+        });
+
         findViewById(R.id.progress1).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -489,7 +496,7 @@ public class MainActivity extends ActionBarActivity implements
         ThemeSingleton.get().positiveColor = color;
         ThemeSingleton.get().neutralColor = color;
         ThemeSingleton.get().negativeColor = color;
-        ThemeSingleton.get().progressColor = color;
+        ThemeSingleton.get().widgetColor = color;
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
             getWindow().setStatusBarColor(darker);
     }
@@ -542,7 +549,19 @@ public class MainActivity extends ActionBarActivity implements
                 .show();
     }
 
-    public void showProgressDialog(boolean indeterminate) {
+    private void showInputDialog() {
+        new MaterialDialog.Builder(this)
+                .title(R.string.input)
+                .content(R.string.input_content)
+                .input(R.string.input_hint, 0, new MaterialDialog.InputCallback() {
+                    @Override
+                    public void onInput(MaterialDialog dialog, CharSequence input) {
+                        showToast("Hello, " + input.toString() + "!");
+                    }
+                }).show();
+    }
+
+    private void showProgressDialog(boolean indeterminate) {
         if (indeterminate) {
             new MaterialDialog.Builder(this)
                     .title(R.string.progress_dialog)

+ 7 - 0
sample/src/main/res/layout/activity_main.xml

@@ -149,6 +149,13 @@
             android:text="@string/folder_chooser"
             android:layout_marginTop="@dimen/sample_button_spacing" />
 
+        <Button
+            android:id="@+id/input"
+            android:layout_width="match_parent"
+            android:layout_height="56dp"
+            android:text="@string/input"
+            android:layout_marginTop="@dimen/sample_button_spacing" />
+
         <Button
             android:id="@+id/progress1"
             android:layout_width="match_parent"

+ 3 - 0
sample/src/main/res/values/strings.xml

@@ -148,5 +148,8 @@
 
     <!-- Optional button to Skip a PreferenceActivity [CHAR LIMIT=20] -->
     <string name="skip_button_label">Skip</string>
+    <string name="input">Input</string>
+    <string name="input_hint">John Appleseed</string>
+    <string name="input_content">What\'s your name?</string>
 
 </resources>