Android: Cloning a Drawable in Order to Make a Statelistdrawable with Filters

Android: Cloning a drawable in order to make a StateListDrawable with filters

Try the following:

Drawable clone = drawable.getConstantState().newDrawable();

Adding a color filter to a Drawable changes all Buttons using the same Drawable

Example that should work for you:

Drawable buttonBackground = context.getResources().getDrawable(R.drawable.bg);
buttonBackground = buttonBackground.mutate();

//Set your filter here

StateListDrawable to switch colorfilters

OK, I never got the above code to work, so here's what I ended up doing.

First, I subclassed LayerDrawable:

public class StateDrawable extends LayerDrawable {

public StateDrawable(Drawable[] layers) {
super(layers);
}

@Override
protected boolean onStateChange(int[] states) {
for (int state : states) {
if (state == android.R.attr.state_selected) {
super.setColorFilter(Color.argb(255, 255, 195, 0), PorterDuff.Mode.SRC_ATOP);
} else {
super.setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP);
}
}
return super.onStateChange(states);
}

@Override
public boolean isStateful() {
return true;
}

}

I changed the buildTab() method to the following:

private View buildTab(int icon, int label) {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.tab_button, null);
((ImageView) view.findViewById(R.id.tab_icon)).setImageDrawable(new StateDrawable(new Drawable[] { getResources()
.getDrawable(icon) }));
((TextView) view.findViewById(R.id.tab_text)).setText(getString(label));
return view;
}

I still add the tabs like this:

Intent fooIntent = new Intent().setClass(this, FooActivity.class);
tabHost.addTab(tabHost.newTabSpec(TAB_NAME_INFO).setIndicator(buildTab(R.drawable.tab_icon_info, R.string.info)).setContent(infoIntent));

This works for me, compatible with android 1.6.

StateListDrawable containing Drawables with different bounds

You will have to create "custom" Drawables, but before you go that way, let me invite you (and whoever is involved, often a designer) to re-think a bit what you are doing, some years ago I did a heavy work on programmatically drawn extends Drawables (yet it was awesome) just to trash it few months later in favor of simplicity and practicality, I don't see why you can't achieve something like this with a well made 9-patch (a.k.a. n-patch) rather than hardcode dimensions, anyways before you call me grandpa here is a quick answer that could work for ya:

In example say you are using color drawables:

public class FixedBoundsColorDrawable extends ColorDrawable {
private boolean mFixedBoundsSet = false; // default

public FixedBoundsColorDrawable(int color) {
super(color);
}

@Override
public void setBounds(int left, int top, int right, int bottom) {
if (!mFixedBoundsSet) {
mFixedBoundsSet = true;
super.setBounds(left, top, right, bottom);
}
}
}

With red as pressed and blue as wildcard and your values you get on a Nexus 4:

http://i.imgur.com/854Hl0K.png

You could also create a wrapper to wrap any drawable and call its methods but I would go that way as there are some final methods that you certainly will need.

Android: how to draw an ImageButton using the pressed state drawable for the focused state

Look inside the drawables folder inside the android SDK. You can find all of the nine patch images it uses by default. The ones you want are likely called btn_pressed, btn_focused etc. Or something similar. You can technically refer to them by id in your project but I believe it is suggested that you copy them into your project, because the IDs are not garunteed to stay the same.

How do I make multiple drawables from the same resource unique?

What if you create clones of the Drawable and modify each as required? See Flavio's answer here: Android: Cloning a drawable in order to make a StateListDrawable with filters



Related Topics



Leave a reply



Submit