Change button state by code - android

this is xml code that I use to change the button images in my app, according to the state:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:drawable="#drawable/button_n" />
<item android:state_pressed="true"
android:drawable="#drawable/button_p" />
</selector>
How can I do this by code? I have try this:
StateListDrawable sl = new StateListDrawable();
sl.addState(new int[]{ android.R.attr.state_pressed}, R.drawable.gridcard_button_p);
but addState takes an int array as first argument and a Drawable Object as sedon one (not an int as in my example).
How can I use this method in the right way?

StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
getResources().getDrawable(R.drawable.pressed));
states.addState(new int[] {android.R.attr.state_focused},
getResources().getDrawable(R.drawable.focused));
states.addState(new int[] { },
getResources().getDrawable(R.drawable.normal));
//... like this you can do for remaining
Button.setImageDrawable(states);

Related

how to display android:imageView with GradientDrawable and setImageResource dynamically ?

I want to make ImageView with specific GradientDrawable and make the src = "#drawable/myImage". When I try this code I get all things fine but the src image doesn't display:
leftIcon = (ImageView)rowView.findViewById(R.id.left_icon);
leftIcon.setImageResource(R.drawable.arrow333);
GradientDrawable gd=new GradientDrawable();
gd.setCornerRadii(getRandomFloatArray());
gd.setStroke(5, Color.WHITE);
gd.setColor(values[position].getColor());
GradientDrawable gd_press=new GradientDrawable();
gd_press.setCornerRadii(getRandomFloatArray());
gd_press.setStroke(5, Color.BLUE);
gd_press.setColor(values[position].getColor());
StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed}, gd_press );
states.addState(new int[] {android.R.attr.state_focused}, gd_press);
states.addState(new int[] { }, gd);
leftIcon.setImageResource(R.drawable.arrow333);
leftIcon.setImageDrawable(states);
And my xml file:
<ImageView
android:id="#+id/left_icon"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
That's probably because you are setting a drawable states just right after setting image resource. If you want both the Images visible than apply one as ImageView background and other as a source:
leftIcon.setBackgroundResource(R.drawable.arrow333);
leftIcon.setImageDrawable(states);
OR
leftIcon.setBackgroundResource(states);
leftIcon.setImageDrawable(R.drawable.arrow333);

Get specific drawable from state list drawable

I have a state list drawable, and i want to get a specific drawable from the state list drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:kplus="http://schemas.android.com/apk/res-auto">
<item kplus:key_type_space_alt="true" android:state_pressed="true" android:drawable="#drawable/space_1_pressed" />
<item kplus:key_type_space_alt="true" android:drawable="#drawable/space_1_normal" />
<!-- TopNav keys. -->
<item kplus:key_type_topnav="true" android:state_pressed="true" android:drawable="#drawable/tab_down" />
<item kplus:key_type_topnav="true" android:state_selected="true" android:drawable="#drawable/tab_down" />
<item kplus:key_type_topnav="true" android:drawable="#drawable/tab_normal" />
<!-- TopRow keys. -->
<item kplus:key_type_toprow="true" android:state_pressed="true" android:drawable="#drawable/numeric_presseed" />
<item kplus:key_type_toprow="true" android:drawable="#drawable/numeric_normal" />
</selector>
I select the correct drawable state for each key, something like this:
if (keyIsNumbers) {
if (KPlusInputMethodService.sNumbersState == 2) {
drawableState = mDrawableStatesProvider.KEY_STATE_TOPNAV_CHECKED;
}
}
Now the states are defined like this:
KEY_STATE_TOPNAV_NORMAL = new int[] {keyTypeTopNavAttrId};
KEY_STATE_TOPNAV_PRESSED = new int[] {keyTypeTopNavAttrId, android.R.attr.state_pressed};
KEY_STATE_TOPNAV_CHECKED = new int[] {keyTypeTopNavAttrId, android.R.attr.state_selected};
Now my question is how to extract the correct drawable for each state ? I need to get the 9patch padding of the drawable, because if the state have different padding on 9patch it will get the padding only for the top drawable, and i want to set the padding manually for each key (drawable.getPadding(rect)).
There is no public API to get the drawable from the state.
There are some methods in StateListDrawable but they are #hide with the comment "pending API council".
You can invoke them by reflection... but it's at your own risk !!!. (it may change in future releases)
Those methods are :
getStateDrawableIndex
getStateDrawable
Here is how to proceed (exceptions omitted) :
int[] currentState = view.getDrawableState();
StateListDrawable stateListDrawable = (StateListDrawable)view.getBackground();
Method getStateDrawableIndex = StateListDrawable.class.getMethod("getStateDrawableIndex", int[].class);
Method getStateDrawable = StateListDrawable.class.getMethod("getStateDrawable", int.class);
int index = (int) getStateDrawableIndex.invoke(stateListDrawable,currentState);
Drawable drawable = (Drawable) getStateDrawable.invoke(stateListDrawable,index);
now it is the way to get specific drawable without reflection:
StateListDrawable pressedDrawable = (StateListDrawable) this.mPressed;
final int state = android.R.attr.state_pressed;
final int index = pressedDrawable.findStateDrawableIndex(new int[]{state});
if (index >= 0) {
Drawable drawable = pressedDrawable.getStateDrawable(index);
if (drawable instanceof GradientDrawable) {
((GradientDrawable) drawable).setCornerRadius(mRoundConerRadius);
}
}

How to create selector drawable from color code programmatically in android

I want to create a selector drawable with #000000 for selected and #FFFFFF for unselected state.
How can I create a drawable programmatically?
Currently I am doing it as following:
StateListDrawable states = new StateListDrawable();
ColorDrawable cdPress = new ColorDrawable(0xFF0000);
ColorDrawable cdUnPress = new ColorDrawable(0x0101DF);
states.addState(new int[] { android.R.attr.state_selected}, cdPress);
states.addState(new int[] {-android.R.attr.state_selected}, cdUnPress);
view.setBackgroundDrawable(states);
view.setSelected(isSelected);
create stateListDrawable and pass to the view
StateListDrawable stateListDrawable=new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}getColorDrawable(Colorcode));
stateListDrawable.addState(new int[]{android.R.attr.state_focused},getColorDrawable(Colorcode));
...
mView.setBackground(stateListDrawable);
...
}
private static Drawable getColorDrawable(int colorCode) {
return new ColorDrawable(colorCode);
}

Add Color "#e3bb87" to StateListDrawable programmatically

The reason I need to do this programmatically is that the text color is downloaded and not pre defined in the xml. I read this
Replace selector images programmatically
I only need to know from
StateListDrawable states = new StateListDrawable();
states.addState(new int[] {android.R.attr.state_pressed},
getResources().getDrawable(R.drawable.pressed));
how turn into
states.addState(new int[] {android.R.attr.state_pressed},**theMethodImLookingFor**("#e3bb87"));
forget about getResources().getColor(R.color.anycolor) , the color is not defined in xml
You can use this:
states.addState(new int[] {android.R.attr.state_pressed},
new ColorDrawable(Color.parseColor("#e3bb87")));
I think you are looking for ColorDrawable
you can do something like this:
StateListDrawable states = new StateListDrawable();
int color = 0xff00ff00;
states.addState(new int[] {android.R.attr.state_pressed},
new ColorDrawable(color));
The method would be
new ColorDrawable(Color.parseColor("#e3bb87"))

programmatically create styles in Android without referring to resources

I'm working on an app that reads in text from an XML document and then displays that text on the screen. I want to be able to create a TextAppearanceSpan object programmatically based on parameters given in the XML document (font, size, color, bold/italic, etc.) that don't rely on Resource files (for SpannableStrings in my TextView).
I was looking at the following constructor:
TextAppearanceSpan(String family, int style, int size, ColorStateList color, ColorStateList linkColor)
but I can't seem to find any information on how ColorStateLists work. Is what I'm trying to do even possible?
You can look at the source code for ColorStateList here:
GrepCode: ColorStateList
For example, the following XML selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:color="#color/testcolor1"/>
<item android:state_pressed="true" android:state_enabled="false" android:color="#color/testcolor2" />
<item android:state_enabled="false" android:color="#color/testcolor3" />
<item android:color="#color/testcolor5"/>
</selector>
is equivalent to the following code:
int[][] states = new int[4][];
int[] colors = new int[4];
states[0] = new int[] { android.R.attr.state_focused };
states[1] = new int[] { android.R.attr.state_pressed, -android.R.attr.state_enabled };
states[2] = new int[] { -android.R.attr.state_enabled };
states[3] = new int[0];
colors[0] = getResources().getColor(R.color.testcolor1);
colors[1] = getResources().getColor(R.color.testcolor2);
colors[2] = getResources().getColor(R.color.testcolor3);
colors[3] = getResources().getColor(R.color.testcolor5);
ColorStateList csl = new ColorStateList(states, colors);
The documentation for what a color state and how selectors work is here.

Categories

Resources