Wednesday, March 9, 2011

Tiled bitmaps in layer drawables

This is a bizarre bug that a coworker came across.

There's a cool feature of XML drawables that allows you to tile bitmaps, using android:tileMode. There is also the ability to layer drawables in XML, via the layer list. Naturally, there are some circumstances where you might want to layer bitmaps that are tiled.

It turns out there is a bug in Android with trying to layer a tiled bitmap. Every once in a while, a tiled bitmap in a layer list won't tile. It's not every time (nor even that common) but anything less than a 100% success rate for graphics is problematic.

The solution is to not define the bitmap drawable tileMode in XML, instead defining it dynamically in code. Inflate the drawable in code somehow (either directly, or by inflating a layout that uses the drawable). Grab the drawable, cast it to a LayerDrawable, then retrieve the BitmapDrawable from the layer list (there are a few methods for it, like LayerDrawable.getDrawable()). Then, set the tileMode in code via BitmapDrawable.setTileModeXY().

I've looked through the code and haven't figured out exactly why this bug occurs. I would appreciate any insight; in the meantime, the fix works well enough.