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

Commit dbee9bb3 authored by Teng-Hui Zhu's avatar Teng-Hui Zhu
Browse files

Gradient for VectorDrawable's fill and stroke

Add ComplexColor interface for both GradientColor and ColorStateList.
Set up constant state, factory, theme attrs for GradientColor, while
refactoring the ColorStateList's similar code. (Functionality in CSL should
be the same).

Support themeing in both the root and item level in GradientColor.
For example, both startColor in <gradient> tag or color in <item> tag can
have theme color.
Add tests for both simple and complex cases with themeing etc.

Hook up the native VectorDrawable implementation using 2 extra JNI calls for
simplicity. Such calls only happen at inflate and applyTheme call.

b/22564318

Change-Id: Ibdc564ddb4a7ee0133c6141c4784782f0c93ce0e
parent c0b2f09a
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -506,6 +506,8 @@ package android {
    field public static final int encryptionAware = 16844038; // 0x1010506
    field public static final int end = 16843996; // 0x10104dc
    field public static final int endColor = 16843166; // 0x101019e
    field public static final int endX = 16844051; // 0x1010513
    field public static final int endY = 16844052; // 0x1010514
    field public static final deprecated int endYear = 16843133; // 0x101017d
    field public static final int enterFadeDuration = 16843532; // 0x101030c
    field public static final int entries = 16842930; // 0x10100b2
@@ -881,6 +883,7 @@ package android {
    field public static final int numbersTextColor = 16843937; // 0x10104a1
    field public static final deprecated int numeric = 16843109; // 0x1010165
    field public static final int numericShortcut = 16843236; // 0x10101e4
    field public static final int offset = 16844053; // 0x1010515
    field public static final int onClick = 16843375; // 0x101026f
    field public static final int oneshot = 16843159; // 0x1010197
    field public static final int opacity = 16843550; // 0x101031e
@@ -1128,6 +1131,8 @@ package android {
    field public static final int startColor = 16843165; // 0x101019d
    field public static final int startDelay = 16843746; // 0x10103e2
    field public static final int startOffset = 16843198; // 0x10101be
    field public static final int startX = 16844049; // 0x1010511
    field public static final int startY = 16844050; // 0x1010512
    field public static final deprecated int startYear = 16843132; // 0x101017c
    field public static final int stateListAnimator = 16843848; // 0x1010448
    field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -9949,7 +9954,7 @@ package android.content.res {
    method public final long skip(long) throws java.io.IOException;
  }
  public class ColorStateList implements android.os.Parcelable {
  public class ColorStateList extends android.content.res.ComplexColor implements android.os.Parcelable {
    ctor public ColorStateList(int[][], int[]);
    method public static deprecated 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, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
@@ -9958,13 +9963,18 @@ package android.content.res {
    method public int getColorForState(int[], int);
    method public int getDefaultColor();
    method public boolean isOpaque();
    method public boolean isStateful();
    method public static android.content.res.ColorStateList valueOf(int);
    method public android.content.res.ColorStateList withAlpha(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR;
  }
  public abstract class ComplexColor {
    ctor public ComplexColor();
    method public abstract int getDefaultColor();
    method public boolean isStateful();
  }
  public final class Configuration implements java.lang.Comparable android.os.Parcelable {
    ctor public Configuration();
    ctor public Configuration(android.content.res.Configuration);
@@ -10068,6 +10078,11 @@ package android.content.res {
    field public int uiMode;
  }
  public class GradientColor extends android.content.res.ComplexColor {
    method public static android.content.res.GradientColor createFromXml(android.content.res.Resources, android.content.res.XmlResourceParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public int getDefaultColor();
  }
  public class ObbInfo implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
@@ -10127,6 +10142,7 @@ package android.content.res {
    method public void getValue(java.lang.String, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException;
    method public void getValueForDensity(int, int, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException;
    method public android.content.res.XmlResourceParser getXml(int) throws android.content.res.Resources.NotFoundException;
    method public android.content.res.ComplexColor loadComplexColor(android.util.TypedValue, int, android.content.res.Resources.Theme);
    method public final android.content.res.Resources.Theme newTheme();
    method public android.content.res.TypedArray obtainAttributes(android.util.AttributeSet, int[]);
    method public android.content.res.TypedArray obtainTypedArray(int) throws android.content.res.Resources.NotFoundException;
@@ -10162,6 +10178,7 @@ package android.content.res {
    method public int getChangingConfigurations();
    method public int getColor(int, int);
    method public android.content.res.ColorStateList getColorStateList(int);
    method public android.content.res.ComplexColor getComplexColor(int);
    method public float getDimension(int, float);
    method public int getDimensionPixelOffset(int, int);
    method public int getDimensionPixelSize(int, int);
+19 −2
Original line number Diff line number Diff line
@@ -601,6 +601,8 @@ package android {
    field public static final int encryptionAware = 16844038; // 0x1010506
    field public static final int end = 16843996; // 0x10104dc
    field public static final int endColor = 16843166; // 0x101019e
    field public static final int endX = 16844051; // 0x1010513
    field public static final int endY = 16844052; // 0x1010514
    field public static final deprecated int endYear = 16843133; // 0x101017d
    field public static final int enterFadeDuration = 16843532; // 0x101030c
    field public static final int entries = 16842930; // 0x10100b2
@@ -976,6 +978,7 @@ package android {
    field public static final int numbersTextColor = 16843937; // 0x10104a1
    field public static final deprecated int numeric = 16843109; // 0x1010165
    field public static final int numericShortcut = 16843236; // 0x10101e4
    field public static final int offset = 16844053; // 0x1010515
    field public static final int onClick = 16843375; // 0x101026f
    field public static final int oneshot = 16843159; // 0x1010197
    field public static final int opacity = 16843550; // 0x101031e
@@ -1227,6 +1230,8 @@ package android {
    field public static final int startColor = 16843165; // 0x101019d
    field public static final int startDelay = 16843746; // 0x10103e2
    field public static final int startOffset = 16843198; // 0x10101be
    field public static final int startX = 16844049; // 0x1010511
    field public static final int startY = 16844050; // 0x1010512
    field public static final deprecated int startYear = 16843132; // 0x101017c
    field public static final int stateListAnimator = 16843848; // 0x1010448
    field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -10349,7 +10354,7 @@ package android.content.res {
    method public final long skip(long) throws java.io.IOException;
  }
  public class ColorStateList implements android.os.Parcelable {
  public class ColorStateList extends android.content.res.ComplexColor implements android.os.Parcelable {
    ctor public ColorStateList(int[][], int[]);
    method public static deprecated 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, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
@@ -10358,13 +10363,18 @@ package android.content.res {
    method public int getColorForState(int[], int);
    method public int getDefaultColor();
    method public boolean isOpaque();
    method public boolean isStateful();
    method public static android.content.res.ColorStateList valueOf(int);
    method public android.content.res.ColorStateList withAlpha(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR;
  }
  public abstract class ComplexColor {
    ctor public ComplexColor();
    method public abstract int getDefaultColor();
    method public boolean isStateful();
  }
  public final class Configuration implements java.lang.Comparable android.os.Parcelable {
    ctor public Configuration();
    ctor public Configuration(android.content.res.Configuration);
@@ -10468,6 +10478,11 @@ package android.content.res {
    field public int uiMode;
  }
  public class GradientColor extends android.content.res.ComplexColor {
    method public static android.content.res.GradientColor createFromXml(android.content.res.Resources, android.content.res.XmlResourceParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public int getDefaultColor();
  }
  public class ObbInfo implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
@@ -10527,6 +10542,7 @@ package android.content.res {
    method public void getValue(java.lang.String, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException;
    method public void getValueForDensity(int, int, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException;
    method public android.content.res.XmlResourceParser getXml(int) throws android.content.res.Resources.NotFoundException;
    method public android.content.res.ComplexColor loadComplexColor(android.util.TypedValue, int, android.content.res.Resources.Theme);
    method public final android.content.res.Resources.Theme newTheme();
    method public android.content.res.TypedArray obtainAttributes(android.util.AttributeSet, int[]);
    method public android.content.res.TypedArray obtainTypedArray(int) throws android.content.res.Resources.NotFoundException;
@@ -10562,6 +10578,7 @@ package android.content.res {
    method public int getChangingConfigurations();
    method public int getColor(int, int);
    method public android.content.res.ColorStateList getColorStateList(int);
    method public android.content.res.ComplexColor getComplexColor(int);
    method public float getDimension(int, float);
    method public int getDimensionPixelOffset(int, int);
    method public int getDimensionPixelSize(int, int);
+19 −2
Original line number Diff line number Diff line
@@ -506,6 +506,8 @@ package android {
    field public static final int encryptionAware = 16844038; // 0x1010506
    field public static final int end = 16843996; // 0x10104dc
    field public static final int endColor = 16843166; // 0x101019e
    field public static final int endX = 16844051; // 0x1010513
    field public static final int endY = 16844052; // 0x1010514
    field public static final deprecated int endYear = 16843133; // 0x101017d
    field public static final int enterFadeDuration = 16843532; // 0x101030c
    field public static final int entries = 16842930; // 0x10100b2
@@ -881,6 +883,7 @@ package android {
    field public static final int numbersTextColor = 16843937; // 0x10104a1
    field public static final deprecated int numeric = 16843109; // 0x1010165
    field public static final int numericShortcut = 16843236; // 0x10101e4
    field public static final int offset = 16844053; // 0x1010515
    field public static final int onClick = 16843375; // 0x101026f
    field public static final int oneshot = 16843159; // 0x1010197
    field public static final int opacity = 16843550; // 0x101031e
@@ -1128,6 +1131,8 @@ package android {
    field public static final int startColor = 16843165; // 0x101019d
    field public static final int startDelay = 16843746; // 0x10103e2
    field public static final int startOffset = 16843198; // 0x10101be
    field public static final int startX = 16844049; // 0x1010511
    field public static final int startY = 16844050; // 0x1010512
    field public static final deprecated int startYear = 16843132; // 0x101017c
    field public static final int stateListAnimator = 16843848; // 0x1010448
    field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -9957,7 +9962,7 @@ package android.content.res {
    method public final long skip(long) throws java.io.IOException;
  }
  public class ColorStateList implements android.os.Parcelable {
  public class ColorStateList extends android.content.res.ComplexColor implements android.os.Parcelable {
    ctor public ColorStateList(int[][], int[]);
    method public static deprecated 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, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
@@ -9966,13 +9971,18 @@ package android.content.res {
    method public int getColorForState(int[], int);
    method public int getDefaultColor();
    method public boolean isOpaque();
    method public boolean isStateful();
    method public static android.content.res.ColorStateList valueOf(int);
    method public android.content.res.ColorStateList withAlpha(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR;
  }
  public abstract class ComplexColor {
    ctor public ComplexColor();
    method public abstract int getDefaultColor();
    method public boolean isStateful();
  }
  public final class Configuration implements java.lang.Comparable android.os.Parcelable {
    ctor public Configuration();
    ctor public Configuration(android.content.res.Configuration);
@@ -10076,6 +10086,11 @@ package android.content.res {
    field public int uiMode;
  }
  public class GradientColor extends android.content.res.ComplexColor {
    method public static android.content.res.GradientColor createFromXml(android.content.res.Resources, android.content.res.XmlResourceParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public int getDefaultColor();
  }
  public class ObbInfo implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
@@ -10135,6 +10150,7 @@ package android.content.res {
    method public void getValue(java.lang.String, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException;
    method public void getValueForDensity(int, int, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException;
    method public android.content.res.XmlResourceParser getXml(int) throws android.content.res.Resources.NotFoundException;
    method public android.content.res.ComplexColor loadComplexColor(android.util.TypedValue, int, android.content.res.Resources.Theme);
    method public final android.content.res.Resources.Theme newTheme();
    method public android.content.res.TypedArray obtainAttributes(android.util.AttributeSet, int[]);
    method public android.content.res.TypedArray obtainTypedArray(int) throws android.content.res.Resources.NotFoundException;
@@ -10170,6 +10186,7 @@ package android.content.res {
    method public int getChangingConfigurations();
    method public int getColor(int, int);
    method public android.content.res.ColorStateList getColorStateList(int);
    method public android.content.res.ComplexColor getComplexColor(int);
    method public float getDimension(int, float);
    method public int getDimensionPixelOffset(int, int);
    method public int getDimensionPixelSize(int, int);
+8 −5
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ import java.util.Arrays;
 * href="{@docRoot}guide/topics/resources/color-list-resource.html">Color State
 * List Resource</a>.</p>
 */
public class ColorStateList implements Parcelable {
public class ColorStateList extends ComplexColor implements Parcelable {
    private static final String TAG = "ColorStateList";

    private static final int DEFAULT_COLOR = Color.RED;
@@ -209,7 +209,7 @@ public class ColorStateList implements Parcelable {
     * @return A new color state list for the current tag.
     */
    @NonNull
    private static ColorStateList createFromXmlInner(@NonNull Resources r,
    static ColorStateList createFromXmlInner(@NonNull Resources r,
            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
            throws XmlPullParserException, IOException {
        final String name = parser.getName();
@@ -340,6 +340,7 @@ public class ColorStateList implements Parcelable {
     * @return whether a theme can be applied to this color state list
     * @hide only for resource preloading
     */
    @Override
    public boolean canApplyTheme() {
        return mThemeAttrs != null;
    }
@@ -419,6 +420,7 @@ public class ColorStateList implements Parcelable {
     *         attributes
     * @hide only for resource preloading
     */
    @Override
    public ColorStateList obtainForTheme(Theme t) {
        if (t == null || !canApplyTheme()) {
            return this;
@@ -460,6 +462,7 @@ public class ColorStateList implements Parcelable {
     *         otherwise.
     * @see #getColorForState(int[], int)
     */
    @Override
    public boolean isStateful() {
        return mStateSpecs.length > 1;
    }
@@ -602,14 +605,14 @@ public class ColorStateList implements Parcelable {
     * @return a factory that can create new instances of this ColorStateList
     * @hide only for resource preloading
     */
    public ConstantState<ColorStateList> getConstantState() {
    public ConstantState<ComplexColor> getConstantState() {
        if (mFactory == null) {
            mFactory = new ColorStateListFactory(this);
        }
        return mFactory;
    }

    private static class ColorStateListFactory extends ConstantState<ColorStateList> {
    private static class ColorStateListFactory extends ConstantState<ComplexColor> {
        private final ColorStateList mSrc;

        public ColorStateListFactory(ColorStateList src) {
@@ -628,7 +631,7 @@ public class ColorStateList implements Parcelable {

        @Override
        public ColorStateList newInstance(Resources res, Theme theme) {
            return mSrc.obtainForTheme(theme);
            return (ColorStateList) mSrc.obtainForTheme(theme);
        }
    }

+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content.res;

import android.annotation.ColorInt;
import android.content.res.Resources.Theme;
import android.graphics.Color;

/**
 * Defines an abstract class for the complex color information, like
 * {@link android.content.res.ColorStateList} or {@link android.content.res.GradientColor}
 */
public abstract class ComplexColor {
    /**
     * @return {@code true}  if this ComplexColor changes color based on state, {@code false}
     * otherwise.
     */
    public boolean isStateful() { return false; }

    /**
     * @return the default color.
     */
    @ColorInt
    public abstract int getDefaultColor();

    /**
     * @hide only for resource preloading
     *
     */
    public abstract ConstantState<ComplexColor> getConstantState();

    /**
     * @hide only for resource preloading
     */
    public abstract boolean canApplyTheme();

    /**
     * @hide only for resource preloading
     */
    public abstract ComplexColor obtainForTheme(Theme t);
}
Loading