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" Drawable
s, 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 Drawable
s (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:
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
Sliding Navigation Drawer Not Handling Clicks on Menu Items Android
Embed Activity Feed of a Public Facebook Page Without Forcing User to Login/Allow
Getactionview() of My Menuitem Return Null
Configuration on Demand Is Not Supported by the Current Version of the Android Gradle Plugin
How to Move Main Content with Drawer Layout Left Side
Getting Null Device Id While Registering to Gcm
Moving or Copying Data from One Node to Another in Firebase Database
Mvvmcross Changing Viewmodel Within a Mvxbindablelistview
Android.Os.Networkonmainthreadexception . Need to Use Async Task
Android Java.Util.Concurrent.Timeunit Convert Milliseconds to Minutes
Finding Current Location of the User in Android
Implement Double Click for Button in Android