Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 519494e2 authored by Alan Viverette's avatar Alan Viverette
Browse files

Add support for using ColorStateList in GradientDrawable

BUG: 11373225
Change-Id: Ie62f1546e8694822aadafe9ef1e57ce458a363d6
parent e38b9950
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -7628,8 +7628,11 @@ package android.content.res {
    ctor public ColorStateList(int[][], int[]);
    ctor public ColorStateList(int[][], int[]);
    method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public int describeContents();
    method public int describeContents();
    method public int getColorAt(int);
    method public int getColorForState(int[], int);
    method public int getColorForState(int[], int);
    method public int getCount();
    method public int getDefaultColor();
    method public int getDefaultColor();
    method public int[] getStateSpecAt(int);
    method public boolean isStateful();
    method public boolean isStateful();
    method public static android.content.res.ColorStateList valueOf(int);
    method public static android.content.res.ColorStateList valueOf(int);
    method public android.content.res.ColorStateList withAlpha(int);
    method public android.content.res.ColorStateList withAlpha(int);
@@ -10277,6 +10280,7 @@ package android.graphics.drawable {
    method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
    method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
    method public void setAlpha(int);
    method public void setAlpha(int);
    method public void setColor(int);
    method public void setColor(int);
    method public void setColor(android.content.res.ColorStateList);
    method public void setColorFilter(android.graphics.ColorFilter);
    method public void setColorFilter(android.graphics.ColorFilter);
    method public void setColors(int[]);
    method public void setColors(int[]);
    method public void setCornerRadii(float[]);
    method public void setCornerRadii(float[]);
+25 −0
Original line number Original line Diff line number Diff line
@@ -280,6 +280,31 @@ public class ColorStateList implements Parcelable {
        return defaultColor;
        return defaultColor;
    }
    }


    /**
     * @return the number of state spec to color mappings in the list
     * @see #getColorAt(int)
     * @see #getStateSpecAt(int)
     */
    public int getCount() {
        return mColors.length;
    }

    /**
     * @return the state spec at the specified index in the list
     * @see #getCount()
     */
    public int[] getStateSpecAt(int index) {
        return mStateSpecs[index];
    }

    /**
     * @return the color at the specified index in the list
     * @see #getCount()
     */
    public int getColorAt(int index) {
        return mColors[index];
    }

    /**
    /**
     * Return the default color in this {@link ColorStateList}.
     * Return the default color in this {@link ColorStateList}.
     *
     *
+80 −9
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package android.graphics.drawable;
package android.graphics.drawable;


import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Canvas;
@@ -24,12 +25,12 @@ import android.graphics.ColorFilter;
import android.graphics.DashPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PixelFormat;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Shader;
import android.graphics.Path;
import android.graphics.RadialGradient;
import android.graphics.SweepGradient;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Log;
@@ -479,7 +480,8 @@ public class GradientDrawable extends Drawable {
            mFillPaint.setAlpha(currFillAlpha);
            mFillPaint.setAlpha(currFillAlpha);
            mFillPaint.setDither(mDither);
            mFillPaint.setDither(mDither);
            mFillPaint.setColorFilter(mColorFilter);
            mFillPaint.setColorFilter(mColorFilter);
            if (mColorFilter != null && !mGradientState.mHasSolidColor) {
            if (mColorFilter != null && !mGradientState.mHasSolidColor
                    && mGradientState.mColorStateList == null) {
                mFillPaint.setColor(mAlpha << 24);
                mFillPaint.setColor(mAlpha << 24);
            }
            }
            if (haveStroke) {
            if (haveStroke) {
@@ -610,7 +612,7 @@ public class GradientDrawable extends Drawable {
    }
    }


    /**
    /**
     * <p>Changes this drawbale to use a single color instead of a gradient.</p>
     * <p>Changes this drawable to use a single color instead of a gradient.</p>
     * <p><strong>Note</strong>: changing color will affect all instances
     * <p><strong>Note</strong>: changing color will affect all instances
     * of a drawable loaded from a resource. It is recommended to invoke
     * of a drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the color.</p>
     * {@link #mutate()} before changing the color.</p>
@@ -626,6 +628,45 @@ public class GradientDrawable extends Drawable {
        invalidateSelf();
        invalidateSelf();
    }
    }


    /**
     * Changes this drawable to use a single color state list instead of a
     * gradient.
     * <p>
     * <strong>Note</strong>: changing color will affect all instances of a
     * drawable loaded from a resource. It is recommended to invoke
     * {@link #mutate()} before changing the color.</p>
     *
     * @param colorStateList The color state list used to fill the shape
     * @see #mutate()
     */
    public void setColor(ColorStateList colorStateList) {
        final int color = colorStateList.getColorForState(getState(), 0);
        mGradientState.setColorStateList(colorStateList);
        mFillPaint.setColor(color);
        invalidateSelf();
    }

    @Override
    public boolean setState(int[] stateSet) {
        final ColorStateList stateList = mGradientState.mColorStateList;
        if (stateList != null) {
            final int newColor = stateList.getColorForState(stateSet, 0);
            final int oldColor = mFillPaint.getColor();
            if (oldColor != newColor) {
                mFillPaint.setColor(newColor);
                invalidateSelf();
                return true;
            }
        }

        return super.setState(stateSet);
    }

    @Override
    public boolean isStateful() {
        return super.isStateful() || mGradientState.mColorStateList != null;
    }

    @Override
    @Override
    public int getChangingConfigurations() {
    public int getChangingConfigurations() {
        return super.getChangingConfigurations() | mGradientState.mChangingConfigurations;
        return super.getChangingConfigurations() | mGradientState.mChangingConfigurations;
@@ -791,7 +832,7 @@ public class GradientDrawable extends Drawable {


                // If we don't have a solid color, the alpha channel must be
                // If we don't have a solid color, the alpha channel must be
                // maxed out so that alpha modulation works correctly.
                // maxed out so that alpha modulation works correctly.
                if (!st.mHasSolidColor) {
                if (!st.mHasSolidColor && st.mColorStateList == null) {
                    mFillPaint.setColor(Color.BLACK);
                    mFillPaint.setColor(Color.BLACK);
                }
                }
            }
            }
@@ -967,10 +1008,10 @@ public class GradientDrawable extends Drawable {
            } else if (name.equals("solid")) {
            } else if (name.equals("solid")) {
                a = r.obtainAttributes(attrs,
                a = r.obtainAttributes(attrs,
                        com.android.internal.R.styleable.GradientDrawableSolid);
                        com.android.internal.R.styleable.GradientDrawableSolid);
                int argb = a.getColor(
                final ColorStateList colorStateList = a.getColorStateList(
                        com.android.internal.R.styleable.GradientDrawableSolid_color, 0);
                        com.android.internal.R.styleable.GradientDrawableSolid_color);
                a.recycle();
                a.recycle();
                setColor(argb);
                setColor(colorStateList);
            } else if (name.equals("stroke")) {
            } else if (name.equals("stroke")) {
                a = r.obtainAttributes(attrs,
                a = r.obtainAttributes(attrs,
                        com.android.internal.R.styleable.GradientDrawableStroke);
                        com.android.internal.R.styleable.GradientDrawableStroke);
@@ -1077,6 +1118,7 @@ public class GradientDrawable extends Drawable {
        public int mShape = RECTANGLE;
        public int mShape = RECTANGLE;
        public int mGradient = LINEAR_GRADIENT;
        public int mGradient = LINEAR_GRADIENT;
        public Orientation mOrientation;
        public Orientation mOrientation;
        public ColorStateList mColorStateList;
        public int[] mColors;
        public int[] mColors;
        public int[] mTempColors; // no need to copy
        public int[] mTempColors; // no need to copy
        public float[] mTempPositions; // no need to copy
        public float[] mTempPositions; // no need to copy
@@ -1113,6 +1155,7 @@ public class GradientDrawable extends Drawable {
            mShape = state.mShape;
            mShape = state.mShape;
            mGradient = state.mGradient;
            mGradient = state.mGradient;
            mOrientation = state.mOrientation;
            mOrientation = state.mOrientation;
            mColorStateList = state.mColorStateList;
            if (state.mColors != null) {
            if (state.mColors != null) {
                mColors = state.mColors.clone();
                mColors = state.mColors.clone();
            }
            }
@@ -1178,6 +1221,7 @@ public class GradientDrawable extends Drawable {
        public void setColors(int[] colors) {
        public void setColors(int[] colors) {
            mHasSolidColor = false;
            mHasSolidColor = false;
            mColors = colors;
            mColors = colors;
            mColorStateList = null;
            computeOpacity();
            computeOpacity();
        }
        }
        
        
@@ -1185,6 +1229,14 @@ public class GradientDrawable extends Drawable {
            mHasSolidColor = true;
            mHasSolidColor = true;
            mSolidColor = argb;
            mSolidColor = argb;
            mColors = null;
            mColors = null;
            mColorStateList = null;
            computeOpacity();
        }

        public void setColorStateList(ColorStateList colorStateList) {
            mHasSolidColor = false;
            mColors = null;
            mColorStateList = colorStateList;
            computeOpacity();
            computeOpacity();
        }
        }


@@ -1204,6 +1256,11 @@ public class GradientDrawable extends Drawable {
                return;
                return;
            }
            }


            if (mColorStateList != null && !isOpaque(mColorStateList)) {
                mOpaque = false;
                return;
            }

            if (mHasSolidColor) {
            if (mHasSolidColor) {
                mOpaque = isOpaque(mSolidColor);
                mOpaque = isOpaque(mSolidColor);
                return;
                return;
@@ -1225,6 +1282,16 @@ public class GradientDrawable extends Drawable {
            return ((color >> 24) & 0xff) == 0xff;
            return ((color >> 24) & 0xff) == 0xff;
        }
        }


        private static boolean isOpaque(ColorStateList colors) {
            final int n = colors.getCount();
            for (int i = 0; i < n; i++) {
                if (!isOpaque(colors.getColorAt(i))) {
                    return false;
                }
            }
            return true;
        }

        public void setStroke(int width, int color) {
        public void setStroke(int width, int color) {
            mStrokeWidth = width;
            mStrokeWidth = width;
            mStrokeColor = color;
            mStrokeColor = color;
@@ -1274,6 +1341,10 @@ public class GradientDrawable extends Drawable {
    private void initializeWithState(GradientState state) {
    private void initializeWithState(GradientState state) {
        if (state.mHasSolidColor) {
        if (state.mHasSolidColor) {
            mFillPaint.setColor(state.mSolidColor);
            mFillPaint.setColor(state.mSolidColor);
        } else if (state.mColorStateList != null) {
            final int[] currentState = getState();
            final int stateColor = state.mColorStateList.getColorForState(currentState, 0);
            mFillPaint.setColor(stateColor);
        } else if (state.mColors == null) {
        } else if (state.mColors == null) {
            // If we don't have a solid color and we don't have a gradient,
            // If we don't have a solid color and we don't have a gradient,
            // the app is stroking the shape, set the color to the default
            // the app is stroking the shape, set the color to the default