Skip to content

Instantly share code, notes, and snippets.

@monxalo
Last active October 1, 2020 20:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monxalo/3ef606a54207c8eb7429 to your computer and use it in GitHub Desktop.
Save monxalo/3ef606a54207c8eb7429 to your computer and use it in GitHub Desktop.
A StateListDrawable that automatically adds a pressed state to a drawable, it applies a dark or light filter for this state.
package pt.eco.mobile.android.ui.drawable;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import android.util.SparseArray;
import android.util.StateSet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class HighlightedDrawable extends StateListDrawable {
@IntDef({FILTER_WHITE, FILTER_BLACK})
@Retention(RetentionPolicy.SOURCE)
public @interface Filter {}
public static final int FILTER_WHITE = 0x1;
public static final int FILTER_BLACK = 0x2;
private int currIdx = -1;
private int childrenCount = 0;
private SparseArray<ColorFilter> filterMap;
private final Resources resources;
private final int resDrawableId;
private final int filter;
private static final ColorFilter sWhiteColorFilter =
new PorterDuffColorFilter(Color.argb(150, 255, 255, 255), PorterDuff.Mode.SRC_ATOP);
private static final ColorFilter sBlackColorFilter =
new PorterDuffColorFilter(Color.argb(150, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);
private HighlightedDrawable(Builder builder) {
super();
this.resources = builder.resources;
this.resDrawableId = builder.resDrawableId;
this.filter = builder.filter;
this.filterMap = new SparseArray<>();
init();
}
private void init() {
final Drawable drawable = ResourcesCompat.getDrawable(resources, resDrawableId, null);
final Drawable pressed = drawable.getConstantState().newDrawable(resources);
switch(filter) {
case FILTER_WHITE:
addState(new int[] { android.R.attr.state_pressed }, pressed, sWhiteColorFilter);
break;
case FILTER_BLACK:
addState(new int[] { android.R.attr.state_pressed }, pressed, sBlackColorFilter);
break;
}
addState(StateSet.WILD_CARD, drawable);
}
@Override
public void addState(int[] stateSet, Drawable drawable) {
super.addState(stateSet, drawable);
childrenCount++;
}
public void addState(int[] stateSet, Drawable drawable, ColorFilter colorFilter) {
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);
getCurrent();
currIdx = result ? idx : currIdx;
if (!result) {
setColorFilter(getColorFilterForIdx(currIdx));
}
return result;
}
private ColorFilter getColorFilterForIdx(int idx) {
return filterMap != null ? filterMap.get(idx) : null;
}
public static final class Builder {
private final Resources resources;
private final int resDrawableId;
private int filter = FILTER_BLACK;
public Builder(@NonNull Resources resources, @DrawableRes int resDrawableId) {
this.resources = resources;
this.resDrawableId = resDrawableId;
}
public Builder setFilter(@Filter int filter) {
this.filter = filter;
return this;
}
public HighlightedDrawable build() {
return new HighlightedDrawable(this);
}
}
}
@monxalo
Copy link
Author

monxalo commented Jun 17, 2015

Usage:

new HighlightedDrawable.Builder(res, R.drawable.ic_example)
                .setFilter(HighlightedDrawable.FILTER_BLACK).build()

@abhijitnukalapati
Copy link

@monxalo haven't tested this, but looks good! 👍 you should consider using the annotation IntDef for filter (FILTER_WHITE, FILTER_BLACK)

@monxalo
Copy link
Author

monxalo commented Jul 5, 2015

@abhijitnukalapati Thanks for the sugestion. I added that and also @NotNull for Resources parameter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment