diff --git a/api/current.txt b/api/current.txt index 35a1aee99aa3f..8340265a2810d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -10387,6 +10387,7 @@ package android.graphics.drawable { method public final android.graphics.Paint getPaint(); method public android.graphics.Shader.TileMode getTileModeX(); method public android.graphics.Shader.TileMode getTileModeY(); + method public android.content.res.ColorStateList getTint(); method public boolean hasAntiAlias(); method public boolean hasMipMap(); method public final boolean isAutoMirrored(); @@ -10402,7 +10403,6 @@ package android.graphics.drawable { method public void setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode); method public final void setTileModeY(android.graphics.Shader.TileMode); method public void setTint(android.content.res.ColorStateList); - method public void setTintMode(android.graphics.PorterDuff.Mode); } public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { @@ -10445,6 +10445,7 @@ package android.graphics.drawable { method public final android.graphics.Rect getBounds(); method public android.graphics.drawable.Drawable.Callback getCallback(); method public int getChangingConfigurations(); + method public android.graphics.ColorFilter getColorFilter(); method public android.graphics.drawable.Drawable.ConstantState getConstantState(); method public android.graphics.drawable.Drawable getCurrent(); method public int getIntrinsicHeight(); @@ -10633,13 +10634,13 @@ package android.graphics.drawable { method public void draw(android.graphics.Canvas); method public int getOpacity(); method public android.graphics.Paint getPaint(); + method public android.content.res.ColorStateList getTint(); method public void setAlpha(int); method public void setColorFilter(android.graphics.ColorFilter); method public void setTargetDensity(android.graphics.Canvas); method public void setTargetDensity(android.util.DisplayMetrics); method public void setTargetDensity(int); method public void setTint(android.content.res.ColorStateList); - method public void setTintMode(android.graphics.PorterDuff.Mode); } public class PaintDrawable extends android.graphics.drawable.ShapeDrawable { @@ -10708,6 +10709,7 @@ package android.graphics.drawable { method public android.graphics.Paint getPaint(); method public android.graphics.drawable.ShapeDrawable.ShaderFactory getShaderFactory(); method public android.graphics.drawable.shapes.Shape getShape(); + method public android.content.res.ColorStateList getTint(); method protected boolean inflateTag(java.lang.String, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet); method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint); method public void setAlpha(int); @@ -10718,6 +10720,7 @@ package android.graphics.drawable { method public void setPadding(android.graphics.Rect); method public void setShaderFactory(android.graphics.drawable.ShapeDrawable.ShaderFactory); method public void setShape(android.graphics.drawable.shapes.Shape); + method public void setTint(android.content.res.ColorStateList); } public static abstract class ShapeDrawable.ShaderFactory { diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index af9e2f0bc853e..f7e81b8bd2c7f 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -346,19 +346,24 @@ public class ProgressBar extends View { return out; } else if (drawable instanceof BitmapDrawable) { - final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); + final BitmapDrawable bitmap = (BitmapDrawable) drawable; + final Bitmap tileBitmap = bitmap.getBitmap(); if (mSampleTile == null) { mSampleTile = tileBitmap; } - - final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); + final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); final BitmapShader bitmapShader = new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); shapeDrawable.getPaint().setShader(bitmapShader); - return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, - ClipDrawable.HORIZONTAL) : shapeDrawable; + // Ensure the color filter and tint are propagated. + shapeDrawable.setTint(bitmap.getTint()); + shapeDrawable.setTintMode(bitmap.getTintMode()); + shapeDrawable.setColorFilter(bitmap.getColorFilter()); + + return clip ? new ClipDrawable( + shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable; } return drawable; diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 2f4196a290026..b34c6d5df632c 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -558,6 +558,11 @@ public class BitmapDrawable extends Drawable { invalidateSelf(); } + @Override + public ColorFilter getColorFilter() { + return mBitmapState.mPaint.getColorFilter(); + } + /** * Specifies a tint for this drawable. *
@@ -582,10 +587,21 @@ public class BitmapDrawable extends Drawable { invalidateSelf(); } + /** + * Returns the tint color for this drawable. + * + * @return Color state list to use for tinting this drawable, or null if + * none set + */ + public ColorStateList getTint() { + return mBitmapState.mTint; + } + /** * Specifies the blending mode used to apply tint. * * @param tintMode A Porter-Duff blending mode + * @hide Pending finalization of supported Modes */ public void setTintMode(Mode tintMode) { mBitmapState.mTintMode = tintMode; @@ -595,6 +611,16 @@ public class BitmapDrawable extends Drawable { invalidateSelf(); } + /** + * Returns the blending mode used to apply tint. + * + * @return The Porter-Duff blending mode used to apply tint. + * @hide Pending finalization of supported Modes + */ + public Mode getTintMode() { + return mBitmapState.mTintMode; + } + /** * @hide Candidate for future API inclusion */ diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index a9cf11532e2ab..84211efd74a9b 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -453,12 +453,6 @@ public abstract class Drawable { return 0xFF; } - /** - * Specify an optional color filter for the drawable. Pass null to remove - * any existing color filter. - */ - public abstract void setColorFilter(ColorFilter cf); - /** * @hide Consider for future API inclusion */ @@ -468,6 +462,15 @@ public abstract class Drawable { // For right now only BitmapDrawable has it. } + /** + * Specify an optional color filter for the drawable. Pass {@code null} to + * remove any existing color filter. + * + * @param cf the color filter to apply, or {@code null} to remove the + * existing color filter + */ + public abstract void setColorFilter(ColorFilter cf); + /** * Specify a color and Porter-Duff mode to be the color filter for this * drawable. @@ -476,6 +479,15 @@ public abstract class Drawable { setColorFilter(new PorterDuffColorFilter(color, mode)); } + /** + * Returns the current color filter, or {@code null} if none set. + * + * @return the current color filter, or {@code null} if none set + */ + public ColorFilter getColorFilter() { + return null; + } + /** * Removes the color filter for this drawable. */ diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index aab1fd963737c..aa84f92718580 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -31,7 +31,6 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Region; import android.graphics.PorterDuff.Mode; -import android.graphics.drawable.BitmapDrawable.BitmapState; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.LayoutDirection; @@ -341,10 +340,21 @@ public class NinePatchDrawable extends Drawable { invalidateSelf(); } + /** + * Returns the tint color for this drawable. + * + * @return Color state list to use for tinting this drawable, or null if + * none set + */ + public ColorStateList getTint() { + return mNinePatchState.mTint; + } + /** * Specifies the blending mode used to apply tint. * * @param tintMode A Porter-Duff blending mode + * @hide Pending finalization of supported Modes */ public void setTintMode(Mode tintMode) { mNinePatchState.mTintMode = tintMode; @@ -354,6 +364,16 @@ public class NinePatchDrawable extends Drawable { invalidateSelf(); } + /** + * Returns the blending mode used to apply tint. + * + * @return The Porter-Duff blending mode used to apply tint. + * @hide Pending finalization of supported Modes + */ + public Mode getTintMode() { + return mNinePatchState.mTintMode; + } + @Override public void setDither(boolean dither) { //noinspection PointlessBooleanExpression diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 93f2dc603ee98..817c74f63f059 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -17,7 +17,10 @@ package android.graphics.drawable; import android.graphics.*; +import android.graphics.PorterDuff.Mode; +import android.graphics.drawable.BitmapDrawable.BitmapState; import android.graphics.drawable.shapes.Shape; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.util.AttributeSet; @@ -55,6 +58,7 @@ import java.io.IOException; */ public class ShapeDrawable extends Drawable { private ShapeState mShapeState; + private PorterDuffColorFilter mTintFilter; private boolean mMutated; /** @@ -77,6 +81,11 @@ public class ShapeDrawable extends Drawable { private ShapeDrawable(ShapeState state) { mShapeState = new ShapeState(state); + + if (state.mTint != null) { + final int color = state.mTint.getColorForState(getState(), 0); + mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); + } } /** @@ -211,23 +220,36 @@ public class ShapeDrawable extends Drawable { @Override public void draw(Canvas canvas) { - Rect r = getBounds(); - Paint paint = mShapeState.mPaint; + final Rect r = getBounds(); + final ShapeState state = mShapeState; + final Paint paint = state.mPaint; - int prevAlpha = paint.getAlpha(); - paint.setAlpha(modulateAlpha(prevAlpha, mShapeState.mAlpha)); + final int prevAlpha = paint.getAlpha(); + paint.setAlpha(modulateAlpha(prevAlpha, state.mAlpha)); // only draw shape if it may affect output if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadow) { - if (mShapeState.mShape != null) { + final boolean clearColorFilter; + if (mTintFilter != null && paint.getColorFilter() == null) { + paint.setColorFilter(mTintFilter); + clearColorFilter = true; + } else { + clearColorFilter = false; + } + + if (state.mShape != null) { // need the save both for the translate, and for the (unknown) Shape - int count = canvas.save(); + final int count = canvas.save(); canvas.translate(r.left, r.top); - onDraw(mShapeState.mShape, canvas, paint); + onDraw(state.mShape, canvas, paint); canvas.restoreToCount(count); } else { canvas.drawRect(r, paint); } + + if (clearColorFilter) { + paint.setColorFilter(null); + } } // restore @@ -258,6 +280,64 @@ public class ShapeDrawable extends Drawable { return mShapeState.mAlpha; } + /** + * Specifies a tint for this drawable. + *
+ * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides + * tint. + * + * @param tint Color state list to use for tinting this drawable, or null to + * clear the tint + */ + public void setTint(ColorStateList tint) { + mShapeState.mTint = tint; + if (mTintFilter == null) { + if (tint != null) { + final int color = tint.getColorForState(getState(), 0); + mTintFilter = new PorterDuffColorFilter(color, mShapeState.mTintMode); + } + } else { + if (tint == null) { + mTintFilter = null; + } + } + invalidateSelf(); + } + + /** + * Returns the tint color for this drawable. + * + * @return Color state list to use for tinting this drawable, or null if + * none set + */ + public ColorStateList getTint() { + return mShapeState.mTint; + } + + /** + * Specifies the blending mode used to apply tint. + * + * @param tintMode A Porter-Duff blending mode + * @hide Pending finalization of supported Modes + */ + public void setTintMode(Mode tintMode) { + mShapeState.mTintMode = tintMode; + if (mTintFilter != null) { + mTintFilter.setMode(tintMode); + } + invalidateSelf(); + } + + /** + * Returns the blending mode used to apply tint. + * + * @return The Porter-Duff blending mode used to apply tint. + * @hide Pending finalization of supported Modes + */ + public Mode getTintMode() { + return mShapeState.mTintMode; + } + @Override public void setColorFilter(ColorFilter cf) { mShapeState.mPaint.setColorFilter(cf); @@ -294,6 +374,28 @@ public class ShapeDrawable extends Drawable { updateShape(); } + @Override + protected boolean onStateChange(int[] stateSet) { + final ColorStateList tint = mShapeState.mTint; + if (tint != null) { + final int newColor = tint.getColorForState(stateSet, 0); + final int oldColor = mTintFilter.getColor(); + if (oldColor != newColor) { + mTintFilter.setColor(newColor); + invalidateSelf(); + return true; + } + } + + return false; + } + + @Override + public boolean isStateful() { + final ShapeState s = mShapeState; + return super.isStateful() || (s.mTint != null && s.mTint.isStateful()); + } + /** * Subclasses override this to parse custom subelements. * If you handle it, return true, else return super.inflateTag(...). @@ -408,6 +510,8 @@ public class ShapeDrawable extends Drawable { int mChangingConfigurations; Paint mPaint; Shape mShape; + ColorStateList mTint; + Mode mTintMode; Rect mPadding; int mIntrinsicWidth; int mIntrinsicHeight; @@ -418,6 +522,8 @@ public class ShapeDrawable extends Drawable { if (orig != null) { mPaint = orig.mPaint; mShape = orig.mShape; + mTint = orig.mTint; + mTintMode = orig.mTintMode; mPadding = orig.mPadding; mIntrinsicWidth = orig.mIntrinsicWidth; mIntrinsicHeight = orig.mIntrinsicHeight;