浏览代码

Release 0.6.1

Aidan Follestad 10 年之前
父节点
当前提交
651207c63e

+ 108 - 69
README.md

@@ -46,17 +46,17 @@ for color resources (e.g. `titleColor` and `titleColorRes`).
 
 ```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")
-        .negativeText("Disagree")
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .negativeText(R.string.disagree)
         .show();
 ```
 
 On Lollipop (API 21) or if you use AppCompat, 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 displayde above the action buttons.
+If the content is long enough, it will become scrollable and a divider will be displayed above the action buttons.
 
 ---
 
@@ -86,17 +86,14 @@ But it's highly recommended to use original ```MaterialDialog``` API for new usa
 MaterialDialog supports the display of an icon just like the stock AlertDialog; it will go to the left of the title.
 
 ```java
-Drawable d = // ... get from somewhere...
 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")
-        .icon(d)
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .icon(R.drawable.icon)
         .show();
 ```
 
-You can substitute a `Drawable` instance for a drawable resource ID or attribute ID, which is recommended.
-
 ---
 
 ### Stacked Action Buttons
@@ -106,10 +103,10 @@ buttons to be vertically orientated.
 
 ```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("Turn on speed boost right now!")
-        .negativeText("No thanks")
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.longer_positive)
+        .negativeText(R.string.negative)
         .show();
 ```
 
@@ -124,11 +121,11 @@ action on the far left.
 
 ```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")
-        .negativeText("Disagree")
-        .neutralText("More info")
+        .title(R.string.title)
+        .content(R.string.content)
+        .positiveText(R.string.agree)
+        .negativeText(R.string.disagree)
+        .neutralText(R.string.more_info)
         .show();
 ```
 
@@ -186,8 +183,8 @@ also very simple.
 
 ```java
 new MaterialDialog.Builder(this)
-        .title("Social Networks")
-        .items(new CharSequence[]{"Twitter", "Google+", "Instagram", "Facebook"})
+        .title(R.string.title)
+        .items(R.array.items)
         .itemsCallback(new MaterialDialog.ListCallback() {
             @Override
             public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
@@ -210,23 +207,25 @@ display radio buttons next to list items.
 
 ```java
 new MaterialDialog.Builder(this)
-        .title("Social Networks")
-        .items(new CharSequence[]{"Twitter", "Google+", "Instagram", "Facebook"})
+        .title(R.string.title)
+        .items(R.array.items)
         .itemsCallbackSingleChoice(-1, new MaterialDialog.ListCallback() {
             @Override
             public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
             }
         })
-        .positiveText("Choose")
+        .positiveText(R.string.choose)
         .show();
 ```
 
 If you want to preselect an item, pass an index 0 or greater in place of -1 in `itemsCallbackSingleChoice()`.
-If `autoDismiss` is turned off, then you must manually dismiss the dialog in the callback. Auto dismiss is on by default.
-When `positiveText()` is not used, the callback will be called every time you select an item since no action is
-available to press, without the dialog being dismissed. 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.
+
+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 an item.
 
 ---
 
@@ -238,8 +237,8 @@ display check boxes next to list items, and the callback can return multiple sel
 
 ```java
 new MaterialDialog.Builder(this)
-        .title("Social Networks")
-        .items(new CharSequence[]{"Twitter", "Google+", "Instagram", "Facebook"})
+        .title(R.string.title)
+        .items(R.array.items)
         .itemsCallbackMultiChoice(null, new MaterialDialog.ListCallbackMulti() {
             @Override
             public void onSelection(MaterialDialog dialog, Integer[] which, CharSequence[] text) {
@@ -249,12 +248,15 @@ new MaterialDialog.Builder(this)
         .show();
 ```
 
-If you want to preselect item(s), pass an array of indices in place of null in `itemsCallbackSingleChoice()`.
-For an example, `new Integer[] { 2, 5 }`. If `autoDismiss` is turned off, then you must manually
-dismiss the dialog in the callback. Auto dismiss is on by default. When action buttons are not added, the
-callback will be called every time you select an item since no action is available to press, without the
-dialog being dismissed. 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.
+If you want to preselect any items, pass an array of indices (resource or literal) in place of null
+in `itemsCallbackMultiChoice()`.
+
+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 an item.
 
 ---
 
@@ -291,10 +293,9 @@ Custom views are very easy to implement.
 ```java
 boolean wrapInScrollView = true;
 new MaterialDialog.Builder(this)
-        .title("Google Wifi")
+        .title(R.string.title)
         .customView(R.layout.custom_view, wrapInScrollView)
-        .positiveText("Connect")
-        .positiveColor(Color.parseColor("#03a9f4"))
+        .positiveText(R.string.positive)
         .build()
         .show();
 ```
@@ -319,20 +320,25 @@ buttons. This library makes theming even easier. Here's a basic example:
 
 ```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")
-        .negativeText("Disagree")
+        .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)
         .neutralColorRes(R.color.material_red_500)
         .titleGravity(GravityEnum.CENTER_HORIZONTAL)
-        .titleColor(R.color.material_red_500)
-        .contentColor(Color.WHITE)
+        .contentGravity(GravityEnum.CENTER_HORIZONTAL)
+        .titleColorRes(R.color.material_red_500)
+        .contentColorRes(Color.WHITE)
         .dividerColorRes(R.color.material_pink_500)
         .backgroundColorRes(R.color.material_blue_grey_800)
-        .btnSelectorRes(R.drawable.custom_btn_selector)
-        .selectorRes(R.drawable.custom_list_and_stackedbtn_selector)
+        .btnSelectorStacked(R.drawable.custom_btn_selector_stacked)
+        .btnSelector(R.drawable.custom_btn_selector)
+        .btnSelector(R.drawable.custom_btn_selector_primary, DialogAction.POSITIVE)
+        .listSelector(R.drawable.custom_list_and_stackedbtn_selector)
         .theme(Theme.DARK)
         .show();
 ```
@@ -355,39 +361,57 @@ or operating system. This behavior can be overridden in your Activity themes:
     <item name="md_dark_theme">true</item>
 
     <!--
-        Applies an icon to all dialogs.
+        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_dark_theme">true</item>
+    <item name="md_icon">@drawable/ic_launcher</item>
 
     <!--
-        By default, the title text is black or white based on the theme.
+        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 is derived from the
-        ?android:textColorSecondary OS attribute.
+        By default, the content text color is derived from the
+        ?android:textColorSecondary system attribute.
     -->
     <item name="md_content_color">#9C27B0</item>
 
+
     <!--
-        By default, the accent color is derived from the colorAccent attribute of
-        AppCompat or android:colorAccent attribute of the Material theme.
+        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_accent_color">#673AB7</item>
+    <item name="md_positive_color">#673AB7</item>
 
     <!--
-        By default, the list item text color is black for the light
-        theme and white for the dark theme.
+        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_item_color">#9C27B0</item>
+    <item name="md_neutral_color">#673AB7</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
+        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_background_color">#37474F</item>
+    <item name="md_negative_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
@@ -396,14 +420,29 @@ or operating system. This behavior can be overridden in your Activity themes:
     <item name="md_divider_color">#E91E63</item>
 
     <!--
-        This overrides the selector used on list items and stacked action buttons
+        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_selector">@drawable/selector</item>
+    <item name="md_btn_neutral_selector">@drawable/selector</item>
 
     <!--
-        This overrides the selector used on action buttons
+        This overrides the background selector used on the negative action button.
     -->
-    <item name="md_btn_selector">@drawable/selector</item>
+    <item name="md_btn_negative_selector">@drawable/selector</item>
 
 </style>
 ```

+ 2 - 2
library/build.gradle

@@ -9,7 +9,7 @@ android {
         minSdkVersion 8
         targetSdkVersion 21
         versionCode 1
-        versionName "0.6.0"
+        versionName "0.6.1"
     }
     lintOptions {
         abortOnError false
@@ -27,7 +27,7 @@ publish {
     userOrg = 'drummer-aidan'
     groupId = 'com.afollestad'
     artifactId = 'material-dialogs'
-    version = '0.6.0'
+    version = '0.6.01'
     description = 'A library for implementing Material design styled dialogs across all versions of Android.'
     website = 'https://github.com/afollestad/material-dialogs'
     issueTracker = "${website}/issues"

+ 150 - 101
library/src/main/java/com/afollestad/materialdialogs/MaterialDialog.java

@@ -70,8 +70,6 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
     protected View neutralButton;
     protected View negativeButton;
     protected boolean isStacked;
-    protected boolean alwaysCallMultiChoiceCallback;
-    protected boolean alwaysCallSingleChoiceCallback;
     protected final int defaultItemColor;
     protected ListType listType;
     protected List<Integer> selectedIndicesList;
@@ -108,12 +106,9 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         if (mBuilder.backgroundColor != 0)
             this.view.setBackgroundColor(mBuilder.backgroundColor);
 
-        final int mdAccentColor = DialogUtils.resolveColor(mBuilder.context, R.attr.md_accent_color);
-        if (mdAccentColor != 0) {
-            mBuilder.positiveColor = mdAccentColor;
-            mBuilder.negativeColor = mdAccentColor;
-            mBuilder.neutralColor = mdAccentColor;
-        }
+        mBuilder.positiveColor = DialogUtils.resolveColor(mBuilder.context, R.attr.md_positive_color, mBuilder.positiveColor);
+        mBuilder.neutralColor = DialogUtils.resolveColor(mBuilder.context, R.attr.md_negative_color, mBuilder.neutralColor);
+        mBuilder.negativeColor = DialogUtils.resolveColor(mBuilder.context, R.attr.md_neutral_color, mBuilder.negativeColor);
 
         title = (TextView) view.findViewById(R.id.title);
         icon = (ImageView) view.findViewById(R.id.icon);
@@ -197,13 +192,12 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         boolean adapterProvided = mBuilder.adapter != null;
         if (mBuilder.items != null && mBuilder.items.length > 0 || adapterProvided) {
             listView = (ListView) view.findViewById(R.id.contentListView);
-            listView.setSelector(getSelector());
+            listView.setSelector(getListSelector());
 
             if (!adapterProvided) {
                 // Determine list type
                 if (mBuilder.listCallbackSingle != null) {
                     listType = ListType.SINGLE;
-                    alwaysCallSingleChoiceCallback = builder.alwaysCallSingleChoiceCallback;
                 } else if (mBuilder.listCallbackMulti != null) {
                     listType = ListType.MULTI;
                     if (mBuilder.selectedIndices != null) {
@@ -211,7 +205,6 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
                     } else {
                         selectedIndicesList = new ArrayList<>();
                     }
-                    alwaysCallMultiChoiceCallback = builder.alwaysCallMultiChoiceCallback;
                 } else {
                     listType = ListType.REGULAR;
                 }
@@ -633,33 +626,45 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         invalidateActions();
     }
 
-    private Drawable getSelector() {
-        if (mBuilder.selector != null) {
-            // Check if builder set the selector
-            return mBuilder.selector;
-        } else {
-            // If not, try to get it from the user's global theme
-            Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_selector);
-            if (d != null) return d;
-        }
-        // If it's still null, get the default selector
-        return DialogUtils.resolveDrawable(getContext(), R.attr.md_selector);
+    private Drawable getListSelector() {
+        if (mBuilder.listSelector != 0)
+            return mBuilder.context.getResources().getDrawable(mBuilder.listSelector);
+        final Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_list_selector);
+        if (d != null) return d;
+        return DialogUtils.resolveDrawable(getContext(), R.attr.md_list_selector);
     }
 
-    private Drawable getButtonSelector() {
+    private Drawable getButtonSelector(DialogAction which) {
         if (isStacked) {
-            return getSelector();
+            if (mBuilder.btnSelectorStacked != 0)
+                return mBuilder.context.getResources().getDrawable(mBuilder.btnSelectorStacked);
+            final Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_btn_stacked_selector);
+            if (d != null) return d;
+            return DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_stacked_selector);
         } else {
-            if (mBuilder.btnSelector != null) {
-                // Check if builder set the selector
-                return mBuilder.btnSelector;
-            } else {
-                // If not, try to get it from the user's global theme
-                Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_btn_selector);
-                if (d != null) return d;
+            switch (which) {
+                default: {
+                    if (mBuilder.btnSelectorPositive != 0)
+                        return mBuilder.context.getResources().getDrawable(mBuilder.btnSelectorPositive);
+                    final Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_btn_positive_selector);
+                    if (d != null) return d;
+                    return DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_positive_selector);
+                }
+                case NEUTRAL: {
+                    if (mBuilder.btnSelectorNeutral != 0)
+                        return mBuilder.context.getResources().getDrawable(mBuilder.btnSelectorNeutral);
+                    final Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_btn_neutral_selector);
+                    if (d != null) return d;
+                    return DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_neutral_selector);
+                }
+                case NEGATIVE: {
+                    if (mBuilder.btnSelectorNegative != 0)
+                        return mBuilder.context.getResources().getDrawable(mBuilder.btnSelectorNegative);
+                    final Drawable d = DialogUtils.resolveDrawable(mBuilder.context, R.attr.md_btn_negative_selector);
+                    if (d != null) return d;
+                    return DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_negative_selector);
+                }
             }
-            // If it's still null, get the default selector
-            return DialogUtils.resolveDrawable(getContext(), R.attr.md_btn_selector);
         }
     }
 
@@ -691,7 +696,7 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             setTypeface(positiveTextView, mBuilder.mediumFont);
             positiveTextView.setText(mBuilder.positiveText);
             positiveTextView.setTextColor(getActionTextStateList(mBuilder.positiveColor));
-            setBackgroundCompat(positiveButton, getButtonSelector());
+            setBackgroundCompat(positiveButton, getButtonSelector(DialogAction.POSITIVE));
             positiveButton.setTag(POSITIVE);
             positiveButton.setOnClickListener(this);
         } else {
@@ -705,7 +710,7 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             setTypeface(neutralTextView, mBuilder.mediumFont);
             neutralButton.setVisibility(View.VISIBLE);
             neutralTextView.setTextColor(getActionTextStateList(mBuilder.neutralColor));
-            setBackgroundCompat(neutralButton, getButtonSelector());
+            setBackgroundCompat(neutralButton, getButtonSelector(DialogAction.NEUTRAL));
             neutralTextView.setText(mBuilder.neutralText);
             neutralButton.setTag(NEUTRAL);
             neutralButton.setOnClickListener(this);
@@ -720,7 +725,7 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             setTypeface(negativeTextView, mBuilder.mediumFont);
             negativeButton.setVisibility(View.VISIBLE);
             negativeTextView.setTextColor(getActionTextStateList(mBuilder.negativeColor));
-            setBackgroundCompat(negativeButton, getButtonSelector());
+            setBackgroundCompat(negativeButton, getButtonSelector(DialogAction.NEGATIVE));
             negativeTextView.setText(mBuilder.negativeText);
             negativeButton.setTag(NEGATIVE);
             negativeButton.setOnClickListener(this);
@@ -809,13 +814,13 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
                     if (mBuilder.autoDismiss && mBuilder.positiveText == null) {
                         dismiss();
                         sendSingleChoiceCallback(v);
-                    } else if (alwaysCallSingleChoiceCallback) {
+                    } else if (mBuilder.alwaysCallSingleChoiceCallback) {
                         sendSingleChoiceCallback(v);
                     }
                 } else if (mBuilder.listCallbackMulti != null) {
                     CheckBox cb = (CheckBox) ((LinearLayout) v).getChildAt(0);
                     cb.setChecked(!cb.isChecked());
-                    if (alwaysCallMultiChoiceCallback) {
+                    if (mBuilder.alwaysCallMultiChoiceCallback) {
                         sendMultichoiceCallback();
                     }
                 } else if (mBuilder.autoDismiss) dismiss();
@@ -869,12 +874,21 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
         protected int dividerColor;
         protected int backgroundColor;
         protected int itemColor;
-        protected Drawable selector;
-        protected Drawable btnSelector;
+
+        @DrawableRes
+        protected int listSelector;
+        @DrawableRes
+        protected int btnSelectorStacked;
+        @DrawableRes
+        protected int btnSelectorPositive;
+        @DrawableRes
+        protected int btnSelectorNeutral;
+        @DrawableRes
+        protected int btnSelectorNegative;
 
         public Builder(@NonNull Context context) {
             this.context = context;
-            final int materialBlue = context.getResources().getColor(R.color.md_material_blue_500);
+            final int materialBlue = context.getResources().getColor(R.color.md_material_blue_600);
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                 TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
                 try {
@@ -910,23 +924,33 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             ThemeSingleton s = ThemeSingleton.get();
             theme(s.darkTheme ? Theme.DARK : Theme.LIGHT);
             if (s.titleColor != 0)
-                titleColor(s.titleColor);
+                this.titleColor = s.titleColor;
             if (s.contentColor != 0)
-                contentColor(s.contentColor);
-            if (s.accentColor != 0)
-                accentColor(s.accentColor);
+                this.contentColor = s.contentColor;
+            if (s.positiveColor != 0)
+                this.positiveColor = s.positiveColor;
+            if (s.neutralColor != 0)
+                this.neutralColor = s.neutralColor;
+            if (s.negativeColor != 0)
+                this.negativeColor = s.negativeColor;
             if (s.itemColor != 0)
-                itemColor(s.itemColor);
+                this.itemColor = s.itemColor;
             if (s.icon != null)
-                icon(s.icon);
+                this.icon = s.icon;
             if (s.backgroundColor != 0)
-                backgroundColor(s.backgroundColor);
+                this.backgroundColor = s.backgroundColor;
             if (s.dividerColor != 0)
-                dividerColor(s.dividerColor);
-            if (s.selector != null)
-                selector(s.selector);
-            if (s.btnSelector != null)
-                btnSelector(s.btnSelector);
+                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;
         }
 
         public Builder title(@StringRes int titleRes) {
@@ -944,11 +968,21 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
+        public Builder titleColor(int color) {
+            this.titleColor = color;
+            return this;
+        }
+
         public Builder titleColorRes(@ColorRes int colorRes) {
             titleColor(this.context.getResources().getColor(colorRes));
             return this;
         }
 
+        public Builder titleColorAttr(@AttrRes int colorAttr) {
+            titleColor(DialogUtils.resolveColor(this.context, colorAttr));
+            return this;
+        }
+
         /**
          * Sets the fonts used in the dialog.
          *
@@ -962,11 +996,6 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
-        public Builder titleColor(int color) {
-            this.titleColor = color;
-            return this;
-        }
-
         public Builder icon(Drawable icon) {
             this.icon = icon;
             return this;
@@ -992,6 +1021,11 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
+        public Builder contentColorAttr(@AttrRes int colorAttr) {
+            contentColor(DialogUtils.resolveColor(this.context, colorAttr));
+            return this;
+        }
+
         public Builder content(@StringRes int contentRes) {
             content(this.context.getString(contentRes));
             return this;
@@ -1118,21 +1152,35 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
-        public Builder selectorRes(@DrawableRes int selectorRes) {
-            return selector(this.context.getResources().getDrawable(selectorRes));
+        public Builder listSelector(@DrawableRes int selectorRes) {
+            this.listSelector = selectorRes;
+            return this;
         }
 
-        public Builder selector(Drawable selector) {
-            this.selector = selector;
+        public Builder btnSelectorStacked(@DrawableRes int selectorRes) {
+            this.btnSelectorStacked = selectorRes;
             return this;
         }
 
-        public Builder btnSelectorRes(@DrawableRes int selectorRes) {
-            return btnSelector(this.context.getResources().getDrawable(selectorRes));
+        public Builder btnSelector(@DrawableRes int selectorRes) {
+            this.btnSelectorPositive = selectorRes;
+            this.btnSelectorNeutral = selectorRes;
+            this.btnSelectorNegative = selectorRes;
+            return this;
         }
 
-        public Builder btnSelector(Drawable selector) {
-            this.btnSelector = selector;
+        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;
         }
 
@@ -1163,18 +1211,18 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
-        public Builder positiveColorRes(@ColorRes int colorRes) {
-            positiveColor(this.context.getResources().getColor(colorRes));
+        public Builder positiveColor(int color) {
+            this.positiveColor = color;
             return this;
         }
 
-        public Builder positiveColor(int color) {
-            this.positiveColor = color;
+        public Builder positiveColorRes(@ColorRes int colorRes) {
+            positiveColor(this.context.getResources().getColor(colorRes));
             return this;
         }
 
-        public Builder negativeColorRes(@ColorRes int colorRes) {
-            negativeColor(this.context.getResources().getColor(colorRes));
+        public Builder positiveColorAttr(@AttrRes int colorAttr) {
+            positiveColor(DialogUtils.resolveColor(this.context, colorAttr));
             return this;
         }
 
@@ -1183,8 +1231,14 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
-        public Builder neutralColorRes(@ColorRes int colorRes) {
-            return neutralColor(this.context.getResources().getColor(colorRes));
+        public Builder negativeColorRes(@ColorRes int colorRes) {
+            negativeColor(this.context.getResources().getColor(colorRes));
+            return this;
+        }
+
+        public Builder negativeColorAttr(@AttrRes int colorAttr) {
+            negativeColor(DialogUtils.resolveColor(this.context, colorAttr));
+            return this;
         }
 
         public Builder neutralColor(int color) {
@@ -1192,26 +1246,16 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return this;
         }
 
-        /**
-         * Convience method for setting the positive, neutral, and negative color all at once.
-         *
-         * @param colorRes The new color resource to use.
-         * @return An instance of the Builder so calls can be chained.
-         */
-        public Builder accentColorRes(@ColorRes int colorRes) {
-            return accentColor(this.context.getResources().getColor(colorRes));
+        public Builder neutralColorRes(@ColorRes int colorRes) {
+            return neutralColor(this.context.getResources().getColor(colorRes));
         }
 
-        /**
-         * Convience method for setting the positive, neutral, and negative color all at once.
-         *
-         * @param color The new color to use.
-         * @return An instance of the Builder so calls can be chained.
-         */
-        public Builder accentColor(int color) {
-            this.positiveColor = color;
-            this.negativeColor = color;
-            this.neutralColor = color;
+        public Builder neutralColorAttr(@AttrRes int colorAttr) {
+            return neutralColor(DialogUtils.resolveColor(this.context, colorAttr));
+        }
+
+        public Builder dividerColor(int color) {
+            this.dividerColor = color;
             return this;
         }
 
@@ -1219,8 +1263,12 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return dividerColor(this.context.getResources().getColor(colorRes));
         }
 
-        public Builder dividerColor(int color) {
-            this.dividerColor = color;
+        public Builder dividerColorAttr(@AttrRes int colorAttr) {
+            return dividerColor(DialogUtils.resolveColor(this.context, colorAttr));
+        }
+
+        public Builder backgroundColor(int color) {
+            this.backgroundColor = color;
             return this;
         }
 
@@ -1228,8 +1276,12 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return backgroundColor(this.context.getResources().getColor(colorRes));
         }
 
-        public Builder backgroundColor(int color) {
-            this.backgroundColor = color;
+        public Builder backgroundColorAttr(@AttrRes int colorAttr) {
+            return backgroundColor(DialogUtils.resolveColor(this.context, colorAttr));
+        }
+
+        public Builder itemColor(int color) {
+            this.itemColor = color;
             return this;
         }
 
@@ -1237,9 +1289,8 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             return itemColor(this.context.getResources().getColor(colorRes));
         }
 
-        public Builder itemColor(int color) {
-            this.itemColor = color;
-            return this;
+        public Builder itemColorAttr(@AttrRes int colorAttr) {
+            return itemColor(DialogUtils.resolveColor(this.context, colorAttr));
         }
 
         public Builder callback(ButtonCallback callback) {
@@ -1579,8 +1630,6 @@ public class MaterialDialog extends DialogBase implements View.OnClickListener {
             tv.setTextColor(itemColor);
             setTypeface(tv, mBuilder.regularFont);
             view.setTag(index + ":" + mBuilder.items[index]);
-
-            setBackgroundCompat(view, getSelector());
             return view;
         }
     }

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

@@ -1,6 +1,7 @@
 package com.afollestad.materialdialogs;
 
 import android.graphics.drawable.Drawable;
+import android.support.annotation.DrawableRes;
 
 /**
  * Use of this is discouraged for now; for internal use only. See the Global Theming section of the README.
@@ -22,11 +23,22 @@ public class ThemeSingleton {
     public boolean darkTheme = false;
     public int titleColor = 0;
     public int contentColor = 0;
-    public int accentColor = 0;
+    public int positiveColor = 0;
+    public int neutralColor = 0;
+    public int negativeColor = 0;
     public int itemColor = 0;
     public Drawable icon = null;
     public int backgroundColor = 0;
     public int dividerColor = 0;
-    public Drawable selector;
-    public Drawable btnSelector;
+
+    @DrawableRes
+    public int listSelector = 0;
+    @DrawableRes
+    public int btnSelectorStacked = 0;
+    @DrawableRes
+    public int btnSelectorPositive = 0;
+    @DrawableRes
+    public int btnSelectorNeutral = 0;
+    @DrawableRes
+    public int btnSelectorNegative = 0;
 }

+ 5 - 4
library/src/main/java/com/afollestad/materialdialogs/util/DialogUtils.java

@@ -4,6 +4,7 @@ import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.AttrRes;
 
 /**
  * @author Aidan Follestad (afollestad)
@@ -18,11 +19,11 @@ public class DialogUtils {
         return Color.argb(alpha, red, green, blue);
     }
 
-    public static int resolveColor(Context context, int attr) {
+    public static int resolveColor(Context context, @AttrRes int attr) {
         return resolveColor(context, attr, 0);
     }
 
-    public static int resolveColor(Context context, int attr, int fallback) {
+    public static int resolveColor(Context context, @AttrRes int attr, int fallback) {
         TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr});
         try {
             return a.getColor(0, fallback);
@@ -31,11 +32,11 @@ public class DialogUtils {
         }
     }
 
-    public static Drawable resolveDrawable(Context context, int attr) {
+    public static Drawable resolveDrawable(Context context, @AttrRes int attr) {
         return resolveDrawable(context, attr, null);
     }
 
-    private static Drawable resolveDrawable(Context context, int attr, Drawable fallback) {
+    private static Drawable resolveDrawable(Context context, @AttrRes int attr, Drawable fallback) {
         TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr});
         try {
             Drawable d = a.getDrawable(0);

+ 10 - 4
library/src/main/res/values-v11/styles.xml

@@ -3,16 +3,22 @@
 
     <style name="MD_Light" parent="android:Theme.Holo.Light.Dialog">
         <item name="md_divider">@color/md_divider_black</item>
-        <item name="md_selector">@drawable/md_selector</item>
-        <item name="md_btn_selector">@drawable/md_btn_selector</item>
+        <item name="md_list_selector">@drawable/md_selector</item>
+        <item name="md_btn_stacked_selector">@drawable/md_selector</item>
+        <item name="md_btn_positive_selector">@drawable/md_btn_selector</item>
+        <item name="md_btn_neutral_selector">@drawable/md_btn_selector</item>
+        <item name="md_btn_negative_selector">@drawable/md_btn_selector</item>
 
         <item name="android:windowBackground">@android:color/transparent</item>
     </style>
 
     <style name="MD_Dark" parent="android:Theme.Holo.Dialog">
         <item name="md_divider">@color/md_divider_white</item>
-        <item name="md_selector">@drawable/md_selector_dark</item>
-        <item name="md_btn_selector">@drawable/md_btn_selector_dark</item>
+        <item name="md_list_selector">@drawable/md_selector</item>
+        <item name="md_btn_stacked_selector">@drawable/md_selector</item>
+        <item name="md_btn_positive_selector">@drawable/md_btn_selector_dark</item>
+        <item name="md_btn_neutral_selector">@drawable/md_btn_selector_dark</item>
+        <item name="md_btn_negative_selector">@drawable/md_btn_selector_dark</item>
 
         <item name="android:windowBackground">@android:color/transparent</item>
     </style>

+ 10 - 4
library/src/main/res/values-v21/styles.xml

@@ -3,14 +3,20 @@
 
     <style name="MD_Light" parent="android:Theme.Material.Light.Dialog.Alert">
         <item name="md_divider">@color/md_divider_black</item>
-        <item name="md_selector">?android:selectableItemBackground</item>
-        <item name="md_btn_selector">@drawable/md_btn_selector_ripple</item>
+        <item name="md_list_selector">?android:selectableItemBackground</item>
+        <item name="md_btn_stacked_selector">?android:selectableItemBackground</item>
+        <item name="md_btn_positive_selector">@drawable/md_btn_selector_ripple</item>
+        <item name="md_btn_neutral_selector">@drawable/md_btn_selector_ripple</item>
+        <item name="md_btn_negative_selector">@drawable/md_btn_selector_ripple</item>
     </style>
 
     <style name="MD_Dark" parent="android:Theme.Material.Dialog.Alert">
         <item name="md_divider">@color/md_divider_white</item>
-        <item name="md_selector">?android:selectableItemBackground</item>
-        <item name="md_btn_selector">@drawable/md_btn_selector_ripple_dark</item>
+        <item name="md_list_selector">?android:selectableItemBackground</item>
+        <item name="md_btn_stacked_selector">?android:selectableItemBackground</item>
+        <item name="md_btn_positive_selector">@drawable/md_btn_selector_ripple_dark</item>
+        <item name="md_btn_neutral_selector">@drawable/md_btn_selector_ripple_dark</item>
+        <item name="md_btn_negative_selector">@drawable/md_btn_selector_ripple_dark</item>
     </style>
 
 </resources>

+ 14 - 5
library/src/main/res/values/attrs.xml

@@ -6,14 +6,23 @@
 
     <!-- Accessible global theming attributes -->
     <attr name="md_dark_theme" format="boolean" />
+    <attr name="md_background_color" format="color" />
+
+    <attr name="md_icon" format="reference" />
     <attr name="md_title_color" format="color" />
     <attr name="md_content_color" format="color" />
-    <attr name="md_accent_color" format="color" />
+
+    <attr name="md_positive_color" format="color" />
+    <attr name="md_neutral_color" format="color" />
+    <attr name="md_negative_color" format="color" />
+
     <attr name="md_item_color" format="color" />
-    <attr name="md_icon" format="reference" />
-    <attr name="md_background_color" format="color" />
     <attr name="md_divider_color" format="color" />
-    <attr name="md_selector" format="reference" />
-    <attr name="md_btn_selector" format="reference" />
+    <attr name="md_list_selector" format="reference" />
+
+    <attr name="md_btn_stacked_selector" format="reference" />
+    <attr name="md_btn_positive_selector" format="reference" />
+    <attr name="md_btn_neutral_selector" format="reference" />
+    <attr name="md_btn_negative_selector" format="reference" />
 
 </resources>

+ 2 - 1
library/src/main/res/values/colors.xml

@@ -11,6 +11,7 @@
     <color name="md_divider_black">#10000000</color>
     <color name="md_divider_white">#10FFFFFF</color>
 
-    <color name="md_material_blue_500">#5677fc</color>
+    <color name="md_material_blue_600">#1E88E5</color>
+    <color name="md_material_blue_800">#1565C0</color>
 
 </resources>

+ 11 - 4
library/src/main/res/values/styles.xml

@@ -2,14 +2,21 @@
 
     <style name="MD_Light" parent="Theme_Light_Dialog">
         <item name="md_divider">@color/md_divider_black</item>
-        <item name="md_selector">@drawable/md_selector</item>
-        <item name="md_btn_selector">@drawable/md_btn_selector</item>
+        <item name="md_list_selector">@drawable/md_selector</item>
+        <item name="md_btn_stacked_selector">@drawable/md_selector</item>
+        <item name="md_btn_positive_selector">@drawable/md_btn_selector</item>
+        <item name="md_btn_neutral_selector">@drawable/md_btn_selector</item>
+        <item name="md_btn_negative_selector">@drawable/md_btn_selector</item>
     </style>
 
     <style name="MD_Dark" parent="android:Theme.Dialog">
         <item name="md_divider">@color/md_divider_white</item>
-        <item name="md_selector">@drawable/md_selector_dark</item>
-        <item name="md_btn_selector">@drawable/md_btn_selector_dark</item>
+        <item name="md_list_selector">@drawable/md_selector</item>
+        <item name="md_btn_stacked_selector">@drawable/md_selector</item>
+        <item name="md_btn_positive_selector">@drawable/md_btn_selector_dark</item>
+        <item name="md_btn_neutral_selector">@drawable/md_btn_selector_dark</item>
+        <item name="md_btn_negative_selector">@drawable/md_btn_selector_dark</item>
+
         <item name="android:windowFrame">@null</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowContentOverlay">@null</item>

+ 2 - 2
sample/build.gradle

@@ -8,8 +8,8 @@ android {
         applicationId "com.afollestad.materialdialogssample"
         minSdkVersion 14
         targetSdkVersion 21
-        versionCode 65
-        versionName "0.6.0"
+        versionCode 66
+        versionName "0.6.1"
     }
     lintOptions {
         abortOnError false

二进制
sample/sample.apk


+ 7 - 1
sample/src/main/java/com/afollestad/materialdialogssample/MainActivity.java

@@ -1,6 +1,7 @@
 package com.afollestad.materialdialogssample;
 
 import android.content.DialogInterface;
+import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Build;
 import android.os.Bundle;
@@ -419,7 +420,9 @@ public class MainActivity extends ActionBarActivity implements FolderSelectorDia
             public void onColorSelection(int index, int color, int darker) {
                 selectedColorIndex = index;
                 getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color));
-                ThemeSingleton.get().accentColor = color;
+                ThemeSingleton.get().positiveColor = color;
+                ThemeSingleton.get().neutralColor = color;
+                ThemeSingleton.get().negativeColor = color;
                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                     getWindow().setStatusBarColor(darker);
             }
@@ -439,6 +442,9 @@ public class MainActivity extends ActionBarActivity implements FolderSelectorDia
                 .contentColorRes(android.R.color.white)
                 .backgroundColorRes(R.color.material_blue_grey_800)
                 .dividerColorRes(R.color.material_pink_500)
+                .btnSelector(R.drawable.md_btn_selector_custom, DialogAction.POSITIVE)
+                .positiveColor(Color.WHITE)
+                .negativeColorAttr(android.R.attr.textColorSecondaryInverse)
                 .theme(Theme.DARK)
                 .show();
     }

+ 6 - 0
sample/src/main/res/drawable-v21/md_btn_selector_custom.xml

@@ -0,0 +1,6 @@
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/md_material_blue_600">
+
+    <item android:drawable="@drawable/md_btn_selector_custom_holo" />
+
+</ripple>

+ 7 - 0
sample/src/main/res/drawable-v21/md_btn_selector_custom_holo.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
+
+    <item android:drawable="@drawable/md_btn_selected_custom" android:state_pressed="true" />
+    <item android:drawable="@drawable/md_btn_unselected_custom" />
+
+</selector>

+ 17 - 0
sample/src/main/res/drawable/md_btn_selected_custom.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetBottom="@dimen/md_button_inset_vertical"
+    android:insetLeft="@dimen/md_button_inset_horizontal"
+    android:insetRight="@dimen/md_button_inset_horizontal"
+    android:insetTop="@dimen/md_button_inset_vertical">
+    <shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+        <corners android:radius="@dimen/md_action_corner_radius" />
+        <solid android:color="@color/md_material_blue_800" />
+        <padding
+            android:bottom="@dimen/md_button_padding_vertical"
+            android:left="@dimen/md_button_padding_horizontal"
+            android:right="@dimen/md_button_padding_horizontal"
+            android:top="@dimen/md_button_padding_vertical" />
+    </shape>
+</inset>

+ 7 - 0
sample/src/main/res/drawable/md_btn_selector_custom.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
+
+    <item android:drawable="@drawable/md_btn_selected_custom" android:state_pressed="true" />
+    <item android:drawable="@drawable/md_btn_unselected_custom" />
+
+</selector>

+ 17 - 0
sample/src/main/res/drawable/md_btn_unselected_custom.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetBottom="@dimen/md_button_inset_vertical"
+    android:insetLeft="@dimen/md_button_inset_horizontal"
+    android:insetRight="@dimen/md_button_inset_horizontal"
+    android:insetTop="@dimen/md_button_inset_vertical">
+    <shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+        <corners android:radius="@dimen/md_action_corner_radius" />
+        <solid android:color="@color/md_material_blue_600" />
+        <padding
+            android:bottom="@dimen/md_button_padding_vertical"
+            android:left="@dimen/md_button_padding_horizontal"
+            android:right="@dimen/md_button_padding_horizontal"
+            android:top="@dimen/md_button_padding_vertical" />
+    </shape>
+</inset>