Browse Source

Progress bars will use Lollpop's button tint list, or color filters below. Check boxes and radio buttons will use button tint list on Lollipop MR1 and above, color filters don't work below. Added yet more useful info the README.

Aidan Follestad 10 years ago
parent
commit
02c71b6019

+ 9 - 5
README.md

@@ -245,7 +245,7 @@ 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
+##### 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()`,
@@ -255,6 +255,8 @@ Like action buttons and many other elements of the Material dialog, you can cust
  
 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
@@ -293,7 +295,7 @@ 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
+##### 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()`,
@@ -303,6 +305,8 @@ Like action buttons and many other elements of the Material dialog, you can cust
  
 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
@@ -458,9 +462,9 @@ new MaterialDialog.Builder(this)
 ```
 
 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, check boxes, and radio buttons. Also note
-that each of these methods have 3 variations for setting a color directly, using color resources, and
-using color attributes.
+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
 

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

@@ -5,7 +5,6 @@ import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Color;
-import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.text.method.LinkMovementMethod;
@@ -16,11 +15,11 @@ 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;
 
@@ -331,19 +330,8 @@ 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.widgetColor, PorterDuff.Mode.SRC_ATOP);
-                dialog.mProgress.setIndeterminateDrawable(indDraw);
-            }
-            Drawable regDraw = dialog.mProgress.getProgressDrawable();
-            if (regDraw != null) {
-                regDraw.setColorFilter(builder.widgetColor, PorterDuff.Mode.SRC_ATOP);
-                dialog.mProgress.setProgressDrawable(regDraw);
-            }
+            dialog.mProgress = (MDProgressBar) dialog.view.findViewById(android.R.id.progress);
+            dialog.mProgress.setColorFilter(builder.widgetColor);
 
             if (!builder.mIndeterminateProgress) {
                 dialog.mProgress.setProgress(0);

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

@@ -32,11 +32,11 @@ 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,7 +59,7 @@ 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;

+ 11 - 73
library/src/main/java/com/afollestad/materialdialogs/internal/MDCheckBox.java

@@ -2,19 +2,12 @@ package com.afollestad.materialdialogs.internal;
 
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.AnimatedStateListDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.DrawableContainer;
+import android.content.res.ColorStateList;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.widget.CheckBox;
-import android.widget.CompoundButton;
 
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
+import com.afollestad.materialdialogs.util.DialogUtils;
 
 /**
  * @author Aidan Follestad (afollestad)
@@ -23,86 +16,31 @@ public class MDCheckBox extends CheckBox {
 
     public MDCheckBox(Context context) {
         super(context);
-        init();
     }
 
     public MDCheckBox(Context context, AttributeSet attrs) {
         super(context, attrs);
-        init();
     }
 
     public MDCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        init();
     }
 
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public MDCheckBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        init();
     }
 
-    private void init() {
-        try {
-            Field btnDrawable = CompoundButton.class.getDeclaredField("mButtonDrawable");
-            btnDrawable.setAccessible(true);
-            AnimatedStateListDrawable stateDrawable = (AnimatedStateListDrawable) btnDrawable.get(this);
-
-            Field stateList = AnimatedStateListDrawable.class.getSuperclass().getDeclaredField("mStateListState");
-            stateList.setAccessible(true);
-            DrawableContainer.DrawableContainerState stateListState = (DrawableContainer.DrawableContainerState) stateList.get(stateDrawable);
-
-            Drawable[] mDrawables = stateListState.getChildren();
-
-            Field stateSets = stateListState.getClass().getSuperclass().getDeclaredField("mStateSets");
-            stateSets.setAccessible(true);
-            int[][] stateSetsValues = (int[][]) stateSets.get(stateListState);
-
-            int index = 0;
-            List<Drawable> checkDraws = new ArrayList<>();
-            for (int[] state : stateSetsValues) {
-                if (state == null || state.length == 0) continue;
-                for (int stateSub : state) {
-                    if (stateSub == android.R.attr.state_checked)
-                        checkDraws.add(mDrawables[index]);
-                }
-                index++;
-            }
-            mCheckedDrawables = checkDraws.toArray(new Drawable[checkDraws.size()]);
-
-            Log.v("TEMP", "TEMP");
-
-        } catch (Throwable t) {
-            Log.v("MDCompoundButtonColor", t.getLocalizedMessage());
-        }
-    }
-
-    private int color;
-    private Drawable[] mCheckedDrawables;
-
     public void setColorFilter(int color) {
-        this.color = color;
-        if (mCheckedDrawables != null) {
-            for (Drawable d : mCheckedDrawables)
-                d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-        }
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-        if (mCheckedDrawables != null) {
-            for (Drawable d : mCheckedDrawables)
-                d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-        }
-    }
-
-    @Override
-    public void setChecked(boolean checked) {
-        super.setChecked(checked);
-        if (mCheckedDrawables != null) {
-            for (Drawable d : mCheckedDrawables)
-                d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+        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);
+        }
+    }
+}

+ 11 - 73
library/src/main/java/com/afollestad/materialdialogs/internal/MDRadioButton.java

@@ -2,19 +2,12 @@ package com.afollestad.materialdialogs.internal;
 
 import android.annotation.TargetApi;
 import android.content.Context;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.AnimatedStateListDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.DrawableContainer;
+import android.content.res.ColorStateList;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.CompoundButton;
 import android.widget.RadioButton;
 
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
+import com.afollestad.materialdialogs.util.DialogUtils;
 
 /**
  * @author Aidan Follestad (afollestad)
@@ -23,86 +16,31 @@ public class MDRadioButton extends RadioButton {
 
     public MDRadioButton(Context context) {
         super(context);
-        init();
     }
 
     public MDRadioButton(Context context, AttributeSet attrs) {
         super(context, attrs);
-        init();
     }
 
     public MDRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        init();
     }
 
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     public MDRadioButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        init();
     }
 
-    private void init() {
-        try {
-            Field btnDrawable = CompoundButton.class.getDeclaredField("mButtonDrawable");
-            btnDrawable.setAccessible(true);
-            AnimatedStateListDrawable stateDrawable = (AnimatedStateListDrawable) btnDrawable.get(this);
-
-            Field stateList = AnimatedStateListDrawable.class.getSuperclass().getDeclaredField("mStateListState");
-            stateList.setAccessible(true);
-            DrawableContainer.DrawableContainerState stateListState = (DrawableContainer.DrawableContainerState) stateList.get(stateDrawable);
-
-            Drawable[] mDrawables = stateListState.getChildren();
-
-            Field stateSets = stateListState.getClass().getSuperclass().getDeclaredField("mStateSets");
-            stateSets.setAccessible(true);
-            int[][] stateSetsValues = (int[][]) stateSets.get(stateListState);
-
-            int index = 0;
-            List<Drawable> checkDraws = new ArrayList<>();
-            for (int[] state : stateSetsValues) {
-                if (state == null || state.length == 0) continue;
-                for (int stateSub : state) {
-                    if (stateSub == android.R.attr.state_checked)
-                        checkDraws.add(mDrawables[index]);
-                }
-                index++;
-            }
-            mCheckedDrawables = checkDraws.toArray(new Drawable[checkDraws.size()]);
-
-            Log.v("TEMP", "TEMP");
-
-        } catch (Throwable t) {
-            Log.v("MDCompoundButtonColor", t.getLocalizedMessage());
-        }
-    }
-
-    private int color;
-    private Drawable[] mCheckedDrawables;
-
     public void setColorFilter(int color) {
-        this.color = color;
-        if (mCheckedDrawables != null) {
-            for (Drawable d : mCheckedDrawables)
-                d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-        }
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-        if (mCheckedDrawables != null) {
-            for (Drawable d : mCheckedDrawables)
-                d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
-        }
-    }
-
-    @Override
-    public void setChecked(boolean checked) {
-        super.setChecked(checked);
-        if (mCheckedDrawables != null) {
-            for (Drawable d : mCheckedDrawables)
-                d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+        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);
         }
     }
 }

+ 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_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"