A short post about how to tint drawables and bitmaps to match the current theme.
When designing the themes section of Ready, we wanted to come up with a way of changing not just the basic color aspects of the app, but the icons and other drawables as well. Using the usual method, this would mean creating a png for each color, and switching between them based on the selected theme - a huge overhead in code, and a also an increase in apk size. We also wanted to make adding colors in the future easy, without having to create new resources each and every time.
Google introduced the DrawableCompat class in the v4 support library, which introduces tinting capabilities for pre-Lollipop devices. It has a full-fledged API, even supports tint lists, and mirroring for RTL layouts, but it was a bit heavyweight for our use case, and also you have to wrap the current Drawable with the
Introducing the TintedBitmapDrawable
So we came up with our own implementation, a lightweight BitmapDrawable subclass called TintedBitmapDrawable, with an overridden
draw() method taking care of tinting using a LightingColorFilter. It only consists of three functions, so it doesn’t mean a significant increase in the method count. The tint color can be specified in one of the two extra constructors or via the
And this is how to use it:
Benefits and tips
- Works for images with white and transparent colors.
- No need for multiple drawables of the same icon when an app supports themes, meaning the apk occupies less space.
- Perfect fit with Google’s material icon pack, just download the white .png version and tint it accordingly.
- Also an epic fit with the Palette library.
- If used with list items, cache the drawables.
- Also available in the ToolBar, if assembled programmatically instead of using a menu.xml.
- Create a StateListDrawable with multiple states of different colored drawables from the same image, thus reducing apk size.