Developer

Pro tip: Add more style to Android app images with Lollipop's bitmap tinting API

With Android Lollipop's drawable tinting capabilities, you can add definition of a common color theme across components, and enable dynamic styling to be brand or content aware.

lollipopforest.jpg
Image: Google

One thing that excites me each time a new Android SDK comes out is the advances in the Android graphics subsystem. With its material design specification and more fluid transition engine, Android 5.0 is no slacker. One feature introduced in API 21 is the concept of drawable tinting.

Drawable tinting makes so much sense in a small form factor device like Android that I'm surprised the Google team didn't get around to it sooner. It allows for the definition of a common color theme across components, without requiring lots of custom components to be packed with your APK; more than that, it allows dynamic styling that can be brand or content aware.

The demo I concocted below utilizes the new setTint() method to randomly flash the light on the top of the tree different colors. You can follow along or download and import the entire project directly into Android Studio.

1. Create a new project in Android Studio. You must target a minimum of API 21 (Lollipop) to get access to the new API.

2. To keep things simple, edit your project manifest to force portrait-only orientation.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.authorwjf.colortintedbitmaps" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:configChanges="orientation|keyboardHidden">
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

3. Add two images to your /res/drawable folder: one for your tree (Figure A) and one for the star (Figure B). The tree image is green, but the star one is gray scale so it absorbs the most possible color when the tint is applied.

Figure A

xmastreeblank.png
Image: William J. Francis

Figure B

star.png
Image: William J. Francis

4. In the /res/layout folder, create a linear layout that places the star above the tree via two stacked image views.

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:id="@+id/star"
        android:src="@drawable/star"/>

    <ImageView
        android:layout_below="@+id/star"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/xmas_tree_blank"/>

</RelativeLayout>

5. Create a handler and an associated runnable in the /Java/MainActivity.java file that randomly applies a new tint every half a second.

MainActivity.java
package com.authorwjf.colortintedbitmaps;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ImageView;

import java.util.Random;


public class MainActivity extends Activity {

    private Handler h = new Handler();
    private int[] xmasLights = new int[] {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        h.postDelayed(r, 500);
    }

    private Runnable r = new Runnable() {
        @Override
        public void run() {
            h.removeCallbacks(r);
            ImageView iv = (ImageView) findViewById(R.id.star);
            Random gen = new Random();
            int randomColor = gen.nextInt(xmasLights.length);
            iv.getDrawable().setTint(xmasLights[randomColor]);
            h.postDelayed(r, 500);
        }
    };
}

Go ahead and run the code on an emulator or device (Figure C) — remember that it must be running Lollipop.

Figure C

xmastreeapp.png
Image: William J. Francis

How easy was that? The use case here is very simple, but I look forward to diving into all the new graphic APIs that Android 5.0 has to offer in 2015!

About William J. Francis

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

Editor's Picks

Free Newsletters, In your Inbox