Get specific drawable from state list drawable - android

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);
}
}

Related

Set GradientDrawable Color in Adapter

I got the color from the button background and store as a String in the database. Later I want to use this color String in my recyclerView adapter to set the color of my TextView. Below is my code:
#Override
public void onBindViewHolder(NoteListAdapter.NoteListHolder holder, int position) {
current = data.get(position);
final String text = current.getText();
final String get_tag_text = current.getTag();
final String get_tag_color = current.getTag_color();
int[] colors = {Color.parseColor(get_tag_color)};
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);
holder.note_text.setText(text);
holder.tv_tag_text.setBackground(gd);
holder.tv_tag_text.setText(get_tag_text);
}
The error I got is "Unknown color". The saved color format in the database is (The saved color format is android.graphics.drawable.GradientDrawable#d1790a4)
Below is the code to get the color from a button background drawable file and also my button xml code
color = (GradientDrawable) tag_watchlist.getBackground().mutate();
tag_color= color.toString();
<Button
android:id="#+id/tag_watch"
style="#style/tag_buttons"
android:background="#drawable/watchlist_button"
android:text="Watchlist" />
drawable file code for the button background
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:padding="10dp">
<solid android:color="#a40ce1"/>
<corners android:radius="10dp"/>
</shape>
Can anyone tell me how to resolve this issue??
Edited answer
You are getting exception Caused by: java.lang.IllegalArgumentException: Unknown color mean that you are not passing the color in supported formats to method Color.parseColor.
Make sure you pass the values in following format
#RRGGBB
#AARRGGBB
Here is the valid example
Color.parseColor("#FF4081")
For more information look at documentation Color.parseColor
As per your requirement, you can achieve this API level 24 onward. If you are using current minSdkVersion 24, try below
Change your model class to save color as Integer instead String.
GradientDrawable gradientDrawable = (GradientDrawable) tag_watchlist.getBackground().mutate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
int color = gradientDrawable.getColor().getDefaultColor();
Log.d("TAG","Color is :"+color);
current.setTagColor(color); // where current is your model class
}
To get the color back from model
int color = current.getTagColor();
You need to provide at least two colors for the GradientDrawable the startColor and the endColor
It will probably throw an exception java.lang.IllegalArgumentException: needs >= 2 number of colors with this code:
int[] colors = {Color.parseColor(get_tag_color)};
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);
Change your code with this:
int[] colors = {Color.parseColor(start_color), Color.parseColor(end_color)};
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);
If you have get_tag_color for both of your startColor and endColor then replace accordingly but that won't be helpful with GradientDrawable.

Generate and set random colors on text view background within Recycler View in Android

I am Trying to Generate Random Colors and set the Random color as background of Text View Just Like in GMail app. The Text view is Having a circular background initially set in xml which i have done using shape. I have done some research and used some code available on internet but the changes are not reflecting in my app.
Below is my Recycler View Adapter Class:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.Items> {
ArrayList<GmailDataHolder> data;
Context context;
public RecyclerViewAdapter(ArrayList<GmailDataHolder> data, Context context) {
this.data = data;
this.context = context;
}
#Override
public RecyclerViewAdapter.Items onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.gmail_layout_row, parent, false);
Items i = new Items(v);
return i;
}
#Override
public void onBindViewHolder(final RecyclerViewAdapter.Items holder, int position) {
//Generating Random Color
int randomAndroidColor = holder.androidColors[new Random().nextInt(holder.androidColors.length)];
Drawable background = holder.circleTv.getBackground();
if (background instanceof ShapeDrawable) {
((ShapeDrawable)background).getPaint().setColor(randomAndroidColor);
} else if (background instanceof GradientDrawable) {
((GradientDrawable)background).setColor(randomAndroidColor);
} else if (background instanceof ColorDrawable) {
((ColorDrawable)background).setColor(randomAndroidColor);
}
holder.line1.setText(data.get(position).getLine1());
holder.line2.setText(data.get(position).getLine2() + "...");
holder.line3.setText(data.get(position).getLine3() + "...");
holder.time.setText(data.get(position).getTime());
//get Star Image State from MySql DB
MyFunctions.getStarState(data, holder, position);
holder.circleTv.setText(String.valueOf(data.get(position).getLine1().charAt(0)).toUpperCase());
//Changing Star Image on Click
MyFunctions.starClickListener(holder);
}
#Override
public int getItemCount() {
return data.size();
}
public class Items extends RecyclerView.ViewHolder {
TextView circleTv, line1, line2, line3, time;
int[] androidColors;
public ImageView star;
public Items(View itemView) {
super(itemView);
//Loading Color from resources
androidColors = itemView.getResources().getIntArray(R.array.androidcolors);
circleTv = (TextView) itemView.findViewById(R.id.tv_circle);
line1 = (TextView) itemView.findViewById(R.id.tv_line1);
line2 = (TextView) itemView.findViewById(R.id.tv_line2);
line3 = (TextView) itemView.findViewById(R.id.tv_line3);
time = (TextView) itemView.findViewById(R.id.tv_time);
star = (ImageView) itemView.findViewById(R.id.img_star);
}
}
Colors.xml File:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#dc4538</color>
<color name="colorFacebook">#374dae</color>
<color name="colorCenterFb">#d5617ae6</color>
<color name="colorStartGoogle">#d8dd4c3a</color>
<color name="colorEndGoogle">#dd4c3a</color>
<color name="colorEndLinkedIn">#1887b0</color>
<color name="colorStartLinkedIn">#e31887b0</color>
<color name="colorStrokeLinkedIn">#ec106584</color>
<color name="colorStrokeGoogle">#b73e2e</color>
<color name="colorStrokeFacebook">#e2263a91</color>
<color name="status">#ba3223</color>
<item name="blue" type="color">#FF33B5E5</item>
<item name="purple" type="color">#FFAA66CC</item>
<item name="green" type="color">#FF99CC00</item>
<item name="orange" type="color">#FFFFBB33</item>
<item name="red" type="color">#FFFF4444</item>
<item name="darkblue" type="color">#FF0099CC</item>
<item name="darkpurple" type="color">#FF9933CC</item>
<item name="darkgreen" type="color">#FF669900</item>
<item name="darkorange" type="color">#FFFF8800</item>
<item name="darkred" type="color">#FFCC0000</item>
<integer-array name="androidcolors">
<item>#color/blue</item>
<item>#color/purple</item>
<item>#color/green</item>
<item>#color/orange</item>
<item>#color/red</item>
<item>#color/darkblue</item>
<item>#color/darkpurple</item>
<item>#color/darkgreen</item>
<item>#color/darkorange</item>
<item>#color/darkred</item>
</integer-array>
</resources>
Initially The TextView is having the following Background declared in xml:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#48b3ff"/>
</shape>
Random r = new Random();
int red=r.nextInt(255 - 0 + 1)+0;
int green=r.nextInt(255 - 0 + 1)+0;
int blue=r.nextInt(255 - 0 + 1)+0;
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.OVAL);
draw.setColor(Color.rgb(red,green,blue));
mTextView.setBackground(draw);
// google's material design colours from , 254 colors
// http://www.google.com/design/spec/style/color.html#color-ui-color-palette
public String[] mColors = {
"FFEBEE", "FFCDD2", "EF9A9A", "E57373", "EF5350", "F44336", "E53935", //reds
"D32F2F", "C62828", "B71C1C", "FF8A80", "FF5252", "FF1744", "D50000",
"FCE4EC", "F8BBD0", "F48FB1", "F06292", "EC407A", "E91E63", "D81B60", //pinks
"C2185B", "AD1457", "880E4F", "FF80AB", "FF4081", "F50057", "C51162",
"F3E5F5", "E1BEE7", "CE93D8", "BA68C8", "AB47BC", "9C27B0", "8E24AA", //purples
"7B1FA2", "6A1B9A", "4A148C", "EA80FC", "E040FB", "D500F9", "AA00FF",
"EDE7F6", "D1C4E9", "B39DDB", "9575CD", "7E57C2", "673AB7", "5E35B1", //deep purples
"512DA8", "4527A0", "311B92", "B388FF", "7C4DFF", "651FFF", "6200EA",
"E8EAF6", "C5CAE9", "9FA8DA", "7986CB", "5C6BC0", "3F51B5", "3949AB", //indigo
"303F9F", "283593", "1A237E", "8C9EFF", "536DFE", "3D5AFE", "304FFE",
"E3F2FD", "BBDEFB", "90CAF9", "64B5F6", "42A5F5", "2196F3", "1E88E5", //blue
"1976D2", "1565C0", "0D47A1", "82B1FF", "448AFF", "2979FF", "2962FF",
"E1F5FE", "B3E5FC", "81D4fA", "4fC3F7", "29B6FC", "03A9F4", "039BE5", //light blue
"0288D1", "0277BD", "01579B", "80D8FF", "40C4FF", "00B0FF", "0091EA",
"E0F7FA", "B2EBF2", "80DEEA", "4DD0E1", "26C6DA", "00BCD4", "00ACC1", //cyan
"0097A7", "00838F", "006064", "84FFFF", "18FFFF", "00E5FF", "00B8D4",
"E0F2F1", "B2DFDB", "80CBC4", "4DB6AC", "26A69A", "009688", "00897B", //teal
"00796B", "00695C", "004D40", "A7FFEB", "64FFDA", "1DE9B6", "00BFA5",
"E8F5E9", "C8E6C9", "A5D6A7", "81C784", "66BB6A", "4CAF50", "43A047", //green
"388E3C", "2E7D32", "1B5E20", "B9F6CA", "69F0AE", "00E676", "00C853",
"F1F8E9", "DCEDC8", "C5E1A5", "AED581", "9CCC65", "8BC34A", "7CB342", //light green
"689F38", "558B2F", "33691E", "CCFF90", "B2FF59", "76FF03", "64DD17",
"F9FBE7", "F0F4C3", "E6EE9C", "DCE775", "D4E157", "CDDC39", "C0CA33", //lime
"A4B42B", "9E9D24", "827717", "F4FF81", "EEFF41", "C6FF00", "AEEA00",
"FFFDE7", "FFF9C4", "FFF590", "FFF176", "FFEE58", "FFEB3B", "FDD835", //yellow
"FBC02D", "F9A825", "F57F17", "FFFF82", "FFFF00", "FFEA00", "FFD600",
"FFF8E1", "FFECB3", "FFE082", "FFD54F", "FFCA28", "FFC107", "FFB300", //amber
"FFA000", "FF8F00", "FF6F00", "FFE57F", "FFD740", "FFC400", "FFAB00",
"FFF3E0", "FFE0B2", "FFCC80", "FFB74D", "FFA726", "FF9800", "FB8C00", //orange
"F57C00", "EF6C00", "E65100", "FFD180", "FFAB40", "FF9100", "FF6D00",
"FBE9A7", "FFCCBC", "FFAB91", "FF8A65", "FF7043", "FF5722", "F4511E", //deep orange
"E64A19", "D84315", "BF360C", "FF9E80", "FF6E40", "FF3D00", "DD2600",
"EFEBE9", "D7CCC8", "BCAAA4", "A1887F", "8D6E63", "795548", "6D4C41", //brown
"5D4037", "4E342E", "3E2723",
"FAFAFA", "F5F5F5", "EEEEEE", "E0E0E0", "BDBDBD", "9E9E9E", "757575", //grey
"616161", "424242", "212121",
"ECEFF1", "CFD8DC", "B0BBC5", "90A4AE", "78909C", "607D8B", "546E7A", //blue grey
"455A64", "37474F", "263238"
};
These are the material design colors.take a random color from it.
// generate a random number
int i = new Random().nextInt(254);
it will generate a random number from 0 to 254
GradientDrawable shape = new GradientDrawable();
shape.setShape(GradientDrawable.OVAL);
shape.setColor(Color.parseColor ("#"+mColors[new Random().nextInt(254)]));
mTextView..setBackground(shape);
it will choose a random color from the list and set as textview background color
This is what you want
on BindViewHolder Method
Random r = new Random();
int red=r.nextInt(255 - 0 + 1)+0;
int green=r.nextInt(255 - 0 + 1)+0;
int blue=r.nextInt(255 - 0 + 1)+0;
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.RECTANGLE);
draw.setColor(Color.rgb(red,green,blue));
holder.viewInside.setBackground(draw);
ps- view inside is the name of the view.
If you want the exact type of Gmail view then you can use this tiny library which will give you the exact thing you want.
https://github.com/amulyakhare/TextDrawable
If you needs to use your own/required colors, just use below code
List<String> colors;
colors=new ArrayList<String>();
colors.add("#5E97F6");
colors.add("#9CCC65");
colors.add("#FF8A65");
colors.add("#9E9E9E");
colors.add("#9FA8DA");
colors.add("#90A4AE");
colors.add("#AED581");
colors.add("#F6BF26");
colors.add("#FFA726");
colors.add("#4DD0E1");
colors.add("#BA68C8");
colors.add("#A1887F");
// all colors used by gmail application :) may be,
// genrating random num from 0 to 11 because you can add more or less
Random r = new Random();
int i1 = r.nextInt(11- 0) + 0;
//genrating shape with colors
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.OVAL);
draw.setColor(Color.parseColor(colors.get(i1)))
// assigning to textview
contact_name_circle.setBackground(draw); //textview
If you want to generate random (any) color you can just do
Color.rgb(Math.random()*255, Math.random()*255, Math.random()*255)
If you want to pick color from your list i would sugest leaving that xml file and making the list in java of all the colors you want and then just simply using randomly picked color from that array.
In your onBindViewHolder you can do the following:
int remainder = getAdapterPosition() % colorsArray.size();
mView.setCardBackgroundColor(Color.parseColor(colorsArray.get(remainder)));
In this way, each RecyclerView item will show the same color on scrolling and also each time when user will see this list.

Obtaining themed attributes from built in Android styles

Given a Context that has been themed with AppTheme (shown below), is it possible to programmatically obtain the color #ff11cc00 without referencing R.style.MyButtonStyle, R.style.AppTheme, or android.R.style.Theme_Light?
The objective is to obtain the button text color that was set by the theme without being bound to a particular theme or app-declared resource. Using android.R.style.Widget_Button and android.R.attr.textColor is okay.
<style name="AppTheme" parent="Theme.Light">
<item name="android:buttonStyle">#style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="android:style/Widget.Button">
<item name="android:textColor">#ff11cc00</item>
</style>
Try the following:
TypedValue outValue = new TypedValue();
Theme theme = context.getTheme();
theme.resolveAttribute(android.R.attr.buttonStyle, outValue , true);
int[] attributes = new int[1];
attributes[0] = android.R.attr.textColor;
TypedArray styledAttributes = theme.obtainStyledAttributes(outValue.resourceId, attributes);
int color = styledAttributes.getColor(0, 0);
I can think of this round about way, may be someone else will know better:
int theme ;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD) {
theme = android.R.style.Theme;
} else {
theme = android.R.style.Theme_DeviceDefault;
}
ContextThemeWrapper wrapper = new ContextThemeWrapper(context, theme);
Button button = new Button(wrapper);
ColorStateList colorStateList = button.getTextColors();
colorStateList.getColorForState(button.getDrawableState(), R.color.default_color);

Constructing a RatingBar using images loaded from the web

I have a form which I'm dynamically generating from data I receive from a web service. This web service provides images which need to be used in the creation of input elements. I'm having difficuly in setting the progressDrawable of a RatingBar. Though XML I'm able to apply a custom image using the following as the progressDrawable:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+android:id/background" android:drawable="#drawable/custom_star" />
<item android:id="#+android:id/secondaryProgress" android:drawable="#drawable/custom_star" />
<item android:id="#+android:id/progress" android:drawable="#drawable/custom_star" />
</layer-list>
where custom_star is a simple .png image, and with #android:style/Widget.RatingBar as the RatingBar style. This works fine:
but I'm wanting to change custom_star dynamically.
In code, I have tried setting the progress drawable using a bitmap directly:
Drawable d = new BitmapDrawable(getResources(), downloadedImage);
ratingBar.setProgressDrawable(d);
and also by constructing a layer-list:
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] {
getResources().getDrawable(R.drawable.custom_star),
getResources().getDrawable(R.drawable.custom_star),
getResources().getDrawable(R.drawable.custom_star)
});
layerDrawable.setId(0, android.R.id.background);
layerDrawable.setId(1, android.R.id.secondaryProgress);
layerDrawable.setId(2, android.R.id.progress);
ratingBar.setProgressDrawable(layerDrawable);
Neither works for me; both result in the custom_star drawable appearing once, stretched by the dimensions of the RatingBar:
Any ideas?
Update:
Luksprog's answer below has made an improvement, but I'm still having a couple of issues. Now, the star drawable is not stretched and the value can be set by touch, but it appears as so with 3/5 selected:
and 5/5 selected:
I believe the scaling of the images can be fixed with a few tweaks, but annoyingly the secondaryProgress drawable doesn't seem to be set - the drawable used for the greyed out not-selected stars. Without that, it's not very usable.
Any ideas?
When using the default progressDrawable or a progressDrawable set through a theme all will be ok as in the constructor for the RatingBar(its superclass ProgressBar to be more precise) widget a method will be called to "make tiles" from that drawable. When using the setProgressDrawable method this doesn't happen and if you pass a simple BitmapDrawable or a LayerDrawable(with simple BitmapDrawables) that Drawable will simply be stretched to cover the widget's background area(what you see know).
In order to make it work you would need to manually do what the RatingBar does at start, create the tiles along with the ClipDrawables that it uses. I've written a method for this, following the source code of the ProgressBar widget:
private Drawable buildRatingBarDrawables(Bitmap[] images) {
final int[] requiredIds = { android.R.id.background,
android.R.id.secondaryProgress, android.R.id.progress };
final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
Drawable[] pieces = new Drawable[3];
for (int i = 0; i < 3; i++) {
ShapeDrawable sd = new ShapeDrawable(new RoundRectShape(
roundedCorners, null, null));
BitmapShader bitmapShader = new BitmapShader(images[i],
Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
sd.getPaint().setShader(bitmapShader);
ClipDrawable cd = new ClipDrawable(sd, Gravity.LEFT,
ClipDrawable.HORIZONTAL);
if (i == 0) {
pieces[i] = sd;
} else {
pieces[i] = cd;
}
}
LayerDrawable ld = new LayerDrawable(pieces);
for (int i = 0; i < 3; i++) {
ld.setId(i, requiredIds[i]);
}
return ld;
}
Then you would use the LayerDrawable returned by this method with the setProgressDrawable method. The RatingBar set its width multiplying the width of one of the state bitmaps with the number of stars, so in order to show the right amount of stars this has to be calculated as well.
Your ids are wrong, you have to set
#android:id/background
#android:id/secondaryProgress
#android:id/progress
You can also define a drawable in xml containing your customization
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+android:id/background"
android:drawable="#drawable/star_empty" />
<item android:id="#+android:id/secondaryProgress"
android:drawable="#drawable/star_empty" />
<item android:id="#+android:id/progress"
android:drawable="#drawable/star_full" />
</layer-list>
And you can use setMax on the RatingBar object to set the maximum amount of stars that can be displayed
It's much easier with such solution:
RatingBar ratingBar = new RatingBar(new ContextThemeWrapper(context, R.style.AppTheme_RatingBar), null, 0);

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