/** * Tries to clone and just color filter the drawable. Uses mode SRC_ATOP. * * @param drawable Which drawable to color * @param color Which color to use * @return A colored drawable ready for use */ @SuppressWarnings("RedundantCast") public Drawable colorUnknownDrawable(@Nullable Drawable drawable, int color) { if (drawable instanceof DrawableWrapper || drawable instanceof android.support.v7.graphics.drawable.DrawableWrapper) { drawable = DrawableCompat.wrap(drawable); DrawableCompat.setTint(drawable, color); DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_ATOP); drawable = DrawableCompat.unwrap(drawable); return drawable; } else { try { // noinspection ConstantConditions Drawable copy = drawable.getConstantState().newDrawable(); copy.mutate(); copy.setColorFilter(color, SRC_ATOP); return copy; } catch (Exception e) { if (drawable != null) { Log.d(LOG_TAG, "Failed to color unknown drawable: " + drawable.getClass().getSimpleName()); } return drawable; } } }
/** * Tries to clone and simply color-filter the drawable. Uses {@link PorterDuff.Mode#SRC_ATOP}. * <b>Note</b>: Use this when you don't know which drawable you have. * * @param drawable Which drawable to color * @param color Which color to use * @return A colored drawable ready for use */ @NonNull public static Drawable colorUnknownDrawable(@NonNull final Drawable drawable, @ColorInt final int color) { // check if this is a drawable wrapper, then do coloring by drawable wrapping if (drawable instanceof DrawableWrapper || drawable instanceof android.support.v7.graphics.drawable.DrawableWrapper) { final Drawable wrapResult = colorDrawableWrapped(drawable, color); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR2) { // there is a bug for JellyBean MR2 when this won't work, so.. set the tint filter manually wrapResult.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)); } return wrapResult; } // wrapping failed, do a plain constant state clone try { final Drawable.ConstantState state = drawable.getConstantState(); if (state == null) { // well done android. throw new IllegalStateException("Constant state is unavailable"); } final Drawable copy = drawable.getConstantState().newDrawable().mutate(); copy.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); return copy; } catch (Exception ignored) { return drawable; } }
private Drawable tileify(Drawable drawable, boolean clip) { if (drawable instanceof DrawableWrapper) { Drawable inner = ((DrawableWrapper) drawable).getWrappedDrawable(); if (inner != null) { inner = tileify(inner, clip); ((DrawableWrapper) drawable).setWrappedDrawable(inner); } } else if (drawable instanceof LayerDrawable) { LayerDrawable background = (LayerDrawable) drawable; final int N = background.getNumberOfLayers(); Drawable[] outDrawables = new Drawable[N]; for (int i = 0; i < N; i++) { int id = background.getId(i); outDrawables[i] = tileify(background.getDrawable(i), (id == android.R.id.progress || id == android.R.id.secondaryProgress)); } LayerDrawable newBg = new LayerDrawable(outDrawables); for (int i = 0; i < N; i++) { newBg.setId(i, background.getId(i)); } return newBg; } else if (drawable instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); return (clip) ? new ClipDrawable(bitmapDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : bitmapDrawable; } return drawable; }
public static DrawableWrapper getDrawableWrapper(Drawable drawable) { if (drawable instanceof DrawableWrapper) { return (DrawableWrapper) drawable; } else { Drawable.Callback callback = drawable.getCallback(); if (callback instanceof Drawable) { return getDrawableWrapper((Drawable) callback); } } return null; }
/** * Converts a drawable to a tiled version of itself. It will recursively * traverse layer and state list drawables. */ private Drawable tileify(Drawable drawable, boolean clip) { if (drawable instanceof DrawableWrapper) { Drawable inner = ((DrawableWrapper) drawable).getWrappedDrawable(); if (inner != null) { inner = tileify(inner, clip); ((DrawableWrapper) drawable).setWrappedDrawable(inner); } } else if (drawable instanceof LayerDrawable) { LayerDrawable background = (LayerDrawable) drawable; final int N = background.getNumberOfLayers(); Drawable[] outDrawables = new Drawable[N]; for (int i = 0; i < N; i++) { int id = background.getId(i); outDrawables[i] = tileify(background.getDrawable(i), (id == android.R.id.progress || id == android.R.id.secondaryProgress)); } LayerDrawable newBg = new LayerDrawable(outDrawables); for (int i = 0; i < N; i++) { newBg.setId(i, background.getId(i)); } return newBg; } else if (drawable instanceof BitmapDrawable) { final BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; final Bitmap tileBitmap = bitmapDrawable.getBitmap(); if (mSampleTile == null) { mSampleTile = tileBitmap; } final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); final BitmapShader bitmapShader = new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); shapeDrawable.getPaint().setShader(bitmapShader); shapeDrawable.getPaint().setColorFilter(bitmapDrawable.getPaint().getColorFilter()); return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable; } return drawable; }
static boolean canSafelyMutateDrawable(@NonNull Drawable drawable) { if (drawable instanceof LayerDrawable) { if (VERSION.SDK_INT >= 16) { return true; } return false; } else if (drawable instanceof InsetDrawable) { if (VERSION.SDK_INT < 14) { return false; } return true; } else if (drawable instanceof StateListDrawable) { if (VERSION.SDK_INT < 8) { return false; } return true; } else if (drawable instanceof GradientDrawable) { if (VERSION.SDK_INT < 14) { return false; } return true; } else if (drawable instanceof DrawableContainer) { ConstantState state = drawable.getConstantState(); if (!(state instanceof DrawableContainerState)) { return true; } for (Drawable child : ((DrawableContainerState) state).getChildren()) { if (!canSafelyMutateDrawable(child)) { return false; } } return true; } else if (drawable instanceof DrawableWrapper) { return canSafelyMutateDrawable(((DrawableWrapper) drawable).getWrappedDrawable()); } else { if (drawable instanceof android.support.v7.graphics.drawable.DrawableWrapper) { return canSafelyMutateDrawable(((android.support.v7.graphics.drawable.DrawableWrapper) drawable).getWrappedDrawable()); } return true; } }
/** * Converts a drawable to a tiled version of itself. It will recursively * traverse layer and state list drawables. */ private Drawable tileify(Drawable drawable, boolean clip) { if (drawable instanceof DrawableWrapper) { Drawable inner = ((DrawableWrapper) drawable).getWrappedDrawable(); if (inner != null) { inner = tileify(inner, clip); ((DrawableWrapper) drawable).setWrappedDrawable(inner); } } else if (drawable instanceof LayerDrawable) { LayerDrawable background = (LayerDrawable) drawable; final int N = background.getNumberOfLayers(); Drawable[] outDrawables = new Drawable[N]; for (int i = 0; i < N; i++) { int id = background.getId(i); outDrawables[i] = tileify(background.getDrawable(i), (id == android.R.id.progress || id == android.R.id.secondaryProgress)); } LayerDrawable newBg = new LayerDrawable(outDrawables); for (int i = 0; i < N; i++) { newBg.setId(i, background.getId(i)); } return newBg; } else if (drawable instanceof BitmapDrawable) { final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); if (mSampleTile == null) { mSampleTile = tileBitmap; } 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; } return drawable; }
private Drawable tileify(Drawable paramDrawable, boolean paramBoolean) { if ((paramDrawable instanceof DrawableWrapper)) { Drawable localDrawable2 = ((DrawableWrapper)paramDrawable).getWrappedDrawable(); if (localDrawable2 != null) { Drawable localDrawable3 = tileify(localDrawable2, paramBoolean); ((DrawableWrapper)paramDrawable).setWrappedDrawable(localDrawable3); } } do { Object localObject = paramDrawable; for (;;) { return localObject; if (!(paramDrawable instanceof LayerDrawable)) { break; } LayerDrawable localLayerDrawable = (LayerDrawable)paramDrawable; int i = localLayerDrawable.getNumberOfLayers(); Drawable[] arrayOfDrawable = new Drawable[i]; int j = 0; if (j < i) { int m = localLayerDrawable.getId(j); Drawable localDrawable1 = localLayerDrawable.getDrawable(j); if ((m == 16908301) || (m == 16908303)) {} for (boolean bool = true;; bool = false) { arrayOfDrawable[j] = tileify(localDrawable1, bool); j++; break; } } localObject = new LayerDrawable(arrayOfDrawable); for (int k = 0; k < i; k++) { ((LayerDrawable)localObject).setId(k, localLayerDrawable.getId(k)); } } } while (!(paramDrawable instanceof BitmapDrawable)); Bitmap localBitmap = ((BitmapDrawable)paramDrawable).getBitmap(); if (this.mSampleTile == null) { this.mSampleTile = localBitmap; } ShapeDrawable localShapeDrawable = new ShapeDrawable(new RoundRectShape(new float[] { 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F, 5.0F }, null, null)); BitmapShader localBitmapShader = new BitmapShader(localBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); localShapeDrawable.getPaint().setShader(localBitmapShader); if (paramBoolean) { return new ClipDrawable(localShapeDrawable, 3, 1); } return localShapeDrawable; }