Loading...
  • Microsoft’s MDM solution solves SMB and enterprise needs
    Microsoft’s MDM solution solves SMB and enterprise needs
  • Evaluating peripheral device management software
    Evaluating peripheral device management software
  •  Mobile app revolution means new management tools for IT
    Mobile app revolution means new management tools for IT
  • How to use IP Address Management in Windows Server 2012
    How to use IP Address Management in Windows Server 2012
  • What SDN means to the network administrator
    What SDN means to the network administrator
Software Engineer

Tinting your next Android UI

tinting-your-next-android

Android
is very flexible when it comes to creating a user interface (UI). By utilizing
the Android Drawable class, it is possible to set a widget background to just about any
image you want.

This is a great approach when you own the user experience,
but what happens when you are not creating an app directly for the end user? For
instance, suppose you are creating an app for retailers who want to customize
the color scheme to their corporate colors. Or, you are creating a widget
library for use by other developers. How do you allow someone to adjust the
“theme” of your UI without packaging along an infinite number of
graphic resources? The answer is in the Drawable class.

Each drawable has a color filter that can be applied in a
number of interesting ways to achieve a wide array of variation in a UI at
runtime. When used correctly, a color filter does not replace the original
graphic resource but rather applies the change in hue uniformly; this preserves
shadowing and gradient, while preventing the user from getting too crazy and
inadvertently creating an eyesore. 

This example demonstrates applying a color filter to a standard
Android button widget. You can follow along with the step-by-step tutorial, or download the entire project and import it directly into Eclipse.

1. Create a new Android project in Eclipse. Target
Android 2.2 or higher.

2. We will need two base drawables for our buttons:
one in the normal state and one in the pressed state. When you are working with
color filters, you will achieve the most dramatic result if your base image is
a combination of grays. In the /res/drawable folder, I define two rounded
rectangles to use as our button backgrounds. The first rectangle uses a nice gradient
to produce a 3D effect. The second rectangle is flat and has a sharp outline.

button_normal.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
	<gradient
		android:endColor="#808080"
	    android:centerColor="#ffffff"
	    android:startColor="#c0c0c0"
	    android:angle="270" />
	<corners
	   	android:radius="10dp" />
	<padding
	    android:left="10dp"            
	    android:top="10dp"
	    android:right="10dp"
	    android:bottom="10dp" />
</shape>
button_pressed.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
	<gradient
	    android:endColor="#c0c0c0"
	    android:centerColor="#c0c0c0"
	    android:startColor="#c0c0c0"
	    android:angle="270" />
	<stroke android:width="10px" 
	    android:color="#808080"/>
	<corners
	   	android:radius="10dp" />
	<padding
	    android:left="10dp"            
	    android:top="10dp"
	    android:right="10dp"
	    android:bottom="10dp" />
</shape>

3. In the same folder, let’s create our state list
drawable.

button_states.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:state_pressed="true" 
        android:drawable="@drawable/button_pressed" />
    <item 
        android:state_pressed="false" 
        android:drawable="@drawable/button_normal" />
</selector>

4. In our /res/layout folder, we are ready to
define our widget layout. In this case, we have a linear layout that stacks
five buttons vertically. Each button has its background property set to our
recently created state list.

activity_main.xml
<LinearLayout 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:gravity="center"
    android:layout_margin="8dp"
    android:orientation="vertical"
    android:background="#000000" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:text="Dynamic Tint Effect Demo"
        android:layout_margin="8dp"
        android:textSize="20sp" />
    
    <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content" 
       android:layout_margin="8dp"
       android:id="@+id/button_1"
       android:background="@drawable/button_states"
       android:text="text"/>
    
    <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content" 
       android:layout_margin="8dp"
       android:id="@+id/button_2"
       android:background="@drawable/button_states"
       android:text="text"/>
    
    <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content" 
       android:layout_margin="8dp"
       android:id="@+id/button_3"
       android:background="@drawable/button_states"
       android:text="text"/>
    
    <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content" 
       android:layout_margin="8dp"
       android:id="@+id/button_4"
       android:background="@drawable/button_states"
       android:text="text"/>
    
    <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content" 
       android:layout_margin="8dp"
       android:id="@+id/button_5"
       android:background="@drawable/button_states"
       android:text="text"/>

</LinearLayout>

5. We are ready to code the /src/MainActivity.java
class. We will start by extending the base Activity, implementing an
OnClickListener, and creating our own utility that allows us to get resources by
their text name rather than the more commonly used ID.

MainActivity.java
package com.authorwjf.tinted;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;

public class MainActivity extends Activity implements OnClickListener {

	private String[] colors = {"white", "magenta", "yellow", "cyan", "green"};
	private int index = 0;
	
	
private int getIdFromName(String name) {
		return getResources().getIdentifier(name,"id",getPackageName());
	}

}

6. We will override the OnCreate function. This is
where we wire up our buttons and first make use of our getIdFromName function.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);		
for (int i=0; i<5; i++) {
		String name = "button_"+Integer.toString(i+1);
		findViewById(getIdFromName(name)).setOnClickListener(this);
	}
	onClick(null);
}

7. We are ready to implement the onClick callback. This
is where we apply a color tint — in this case, it is based on the array we
defined previously of “known” Android color names.

@Override
public void onClick(View v) {		
for (int i=0; i<5; i++) {
		String name = "button_"+Integer.toString(i+1);
		((Button)findViewById(getIdFromName(name))).setText(colors[index]);
		int tint = Color.parseColor(colors[index]);
((Button)findViewById(getIdFromName(name))).getBackground().setColorFilter(tint, Mode.MULTIPLY);
	}
	index++;		
if (index>4) index=0;	
}

The app is ready to compile and run. You can check it out on
an emulator or an actual Android device. Each time you press one of the
buttons, they will cycle through the next color in the list.

Figure A: Base UI

white_buttons_AndroidUI_073013.png


Figure B: Yellow tinted UI

yellow_buttons_AndroidUI_073013.pngyellow_buttons_AndroidUI_073013.png


I hope the power of Android’s color filter is sinking
in now. And remember, you can apply this technique to any view in the UI that
allows you to set a background drawable. You can even create a vanilla set of
PNG-based icons and apply a tint to them as well. How slick is that?

Leave a Reply

Your email address will not be published. Required fields are marked *

Show Buttons
Hide Buttons