Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is my class, hacked to support ColorFilter:</p> <p>Usage:</p> <pre><code>final Drawable icon = getResources().getDrawable(iconResId); final Drawable filteredIcon = // this is important icon.getConstantState().newDrawable(); final FilterableStateListDrawable selectorDrawable = new FilterableStateListDrawable(); selectorDrawable.addState(ICON_STATE_SELECTED, filteredIcon, new PorterDuffColorFilter(mIconOverlayColor, PorterDuff.Mode.SRC_ATOP)); selectorDrawable.addState(ICON_STATE_DEFAULT, icon); </code></pre> <p>As you see the ColorFilter is not applied directly to the drawable, it is associated to it while adding a state to the selector Drawable.</p> <p>What's important here is that</p> <ul> <li>you need to create a new drawable from the constant state or you'll modify the constant state and thus any instance of that drawable around your activity.</li> <li>you need to use my custom addState method, it has the same name of the framework method addState but I've added an additional argument (ColorFilter). This method does NOT exist in the framework superclass!</li> </ul> <p>The code (dirty, but work for me):</p> <pre><code>/** * This is an extension to {@link android.graphics.drawable.StateListDrawable} that workaround a bug not allowing * to set a {@link android.graphics.ColorFilter} to the drawable in one of the states., it add a method * {@link #addState(int[], android.graphics.drawable.Drawable, android.graphics.ColorFilter)} for that purpose. */ public class FilterableStateListDrawable extends StateListDrawable { private int currIdx = -1; private int childrenCount = 0; private SparseArray&lt;ColorFilter&gt; filterMap; public FilterableStateListDrawable() { super(); filterMap = new SparseArray&lt;ColorFilter&gt;(); } @Override public void addState(int[] stateSet, Drawable drawable) { super.addState(stateSet, drawable); childrenCount++; } /** * Same as {@link #addState(int[], android.graphics.drawable.Drawable)}, but allow to set a colorFilter associated to this Drawable. * * @param stateSet - An array of resource Ids to associate with the image. * Switch to this image by calling setState(). * @param drawable -The image to show. * @param colorFilter - The {@link android.graphics.ColorFilter} to apply to this state */ public void addState(int[] stateSet, Drawable drawable, ColorFilter colorFilter) { // this is a new custom method, does not exist in parent class int currChild = childrenCount; addState(stateSet, drawable); filterMap.put(currChild, colorFilter); } @Override public boolean selectDrawable(int idx) { if (currIdx != idx) { setColorFilter(getColorFilterForIdx(idx)); } boolean result = super.selectDrawable(idx); // check if the drawable has been actually changed to the one I expect if (getCurrent() != null) { currIdx = result ? idx : currIdx; if (!result) { // it has not been changed, meaning, back to previous filter setColorFilter(getColorFilterForIdx(currIdx)); } } else if (getCurrent() == null) { currIdx = -1; setColorFilter(null); } return result; } private ColorFilter getColorFilterForIdx(int idx) { return filterMap != null ? filterMap.get(idx) : null; } } </code></pre> <p>I've opened a bug about this: <a href="https://code.google.com/p/android/issues/detail?id=60183" rel="nofollow noreferrer">https://code.google.com/p/android/issues/detail?id=60183</a></p> <p>UPDATE: the bug has been fixed in the framework, since Lollipop I think. I think the fix commit is this: <a href="https://android.googlesource.com/platform/frameworks/base/+/729427d%5E!/" rel="nofollow noreferrer">https://android.googlesource.com/platform/frameworks/base/+/729427d%5E!/</a></p> <p>or on Github: <a href="https://github.com/android/platform_frameworks_base/commit/729427d451bc4d4d268335b8dc1ff6404bc1c91e" rel="nofollow noreferrer">https://github.com/android/platform_frameworks_base/commit/729427d451bc4d4d268335b8dc1ff6404bc1c91e</a></p> <p>My workaround should still work after Lollipop, it just don't use the fix by Google.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload