Android StateDrawableBuilder — An easy way to create StateListDrawable programmatically.

A crash caused by an Android Support Library update led me to create an easier way to programmatically generate StateListDrawables. After upgrading Android Support Library to the latest version, I noticed that a crash occurs on older devices (pre-lollipop) when I try to load a selector with vector drawables all from xml. I could replace these vectors with PNGs but I found it more beneficial to keep these assets as vectors unless there was no way around this. For more information about vectors in Android please see: https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88#.p3anbijhl

In an Android Support Library update (23.3), one of the changes listed was:

For AppCompat users, we’ve decided to remove the functionality which let you use vector drawables from resources on pre-Lollipop devices due to issues found in the implementation in version 23.2.0/23.2.1 [https://goo.gl/u5suZB,https://goo.gl/fW5Tyd]. Using app:srcCompat and setImageResource() continues to work.
https://plus.google.com/+AndroidDevelopers/posts/iTDmFiGrVne

It turns out you can still pass app:srcCompat a vector on older devices if you configure your Gradle file to support it. http://stackoverflow.com/questions/35739743/file-res-drawable-abc-ic-ab-back-material-xml-from-drawable-resource-id-0x7f020/35986814

But even after configuring your Gradle file to support vectors on older devices, passing app:srcCompat a selector drawable that includes vectors is not supported. I found out a way to get around this is to create a StateListDrawable, configure it with VectorDrawableCompats, then set your ImageView, ImageButton, TextView’s compound drawable, etc… to use that StateListDrawable.

I rarely worked with StateListDrawables directly because it was so much easier to create them from xml. The class was pretty new to me even though I work with it indirectly through xml every day. I found configuring a StateListDrawable to be pretty strange and unnecessarily annoying. There were so many different combinations of states you can declare in your stateSet array and I noticed that the order of the states added mattered. I played around with StateListDrawable, read through some articles, and then created a builder class that helps generate a simple StateListDrawable. With StateDrawableBuilder, it is simple to tell how your drawable should appear in specific states.

StateDrawableBuilder

Usage Example

It is not the prettiest solution ever but this will enable you to use the latest version of Android Support Library and display selectable vector drawables on pre-lollipop devices.