How to give Android applications a native look and feel

During the past few days I’ve been work on a new Android app; one thing I find very, very important is to make any software look native to the platform it’s running on, and doing that on Android needed some work.

Default theme

So, I installed the Android SDK and the Eclipse plugin, and after working on an initial prototype, I found out that both in a 2.3 real phone, and in the emulator (which runs version 4.0), the lists had bright text over white color, rendering the list almost unusable; the problem here was the default application definition in AndroidManifest.xml:

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

What was wrong is the android:theme field; removing this field will make your application use the default… the problem is that the default changes depending on the android:targetSdkVersion on the same AndroidManifest.xml file:

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="11" />

So, for Android 4.0+, the default theme will be selected depending on that field:

  • For values less than 11, @android:style/Theme
  • Between 11 and 13 @android:style/Theme.Holo
  • For 14 and higher @android:style/Theme.DeviceDefault

Action bar

So, here the obvious choice would be to use a value of 14 or more to use the Theme.DeviceDefault value… but it’s not as easy; the problem here is the “action bar” that was introduced on Android 3.0 .

The “action bar” are the buttons that appear at the right side of the title bar; it uses the same elements as the activity menu, which can have an attribute android:showAsAction that determines wether or not they’re shown in the action bar.

So, if you want to provide compatibility with older Android version you have two options: incorporate your own action bar in older Android versions, or make sure that the important actions (like saving) are shown as buttons.

For the first option, you can implement it yourself (for instance, using the “ActionBarCompat” code sample), or use a third party library like ActionBarSherlock.

I opted for the second option, as the action bar is not a native component in Android versions that are still widely used, and I wanted it to feel as native as possible.

On the onCreate method I added the following:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setUpActionBar();
            // Hide button panel
            findViewById(R.id.buttonpanel).setVisibility(View.GONE);
        }

And created a new method:

    @TargetApi(11)
    private void setUpActionBar() {
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

The @TargetApi(11) annotation is to avoid warnings; you only need to implement this method in the case you want to integrate better with the action bar; in this case, it offers an alternative way to go back to the previous dialog.

Icon colors

After defining your action bar menu items, you probably will want to use icons on them; these are defined by using the android:icon attribute in the menu item definitions.

Here we arrive to an ugly area; the icons are just bitmaps, and they follow certain style (details in the Action Bar Icons Design Guidelines).

So, if you happen to use the Theme.DeviceDefault option, there’s no way to assure that the icons will have the right color for the device at hand, so you’ll need to style the action bar yourself to make sure they’re presented properly.

This is not the case in case that you opt to use a specific theme, like Theme.Holo, which is the option I decided to go for.

An additional advantage of using the Holo theme is that the icons you use will look fine in the Android 2.3 menus; they don’t look completely native, as the system icons have a 3D effect, but they look nice IMHO; of course, if you would like to provide the perfect icons, just specify a different icon set for older versions by providing alternative resources.

Google, listen to me!

I was quite disappointed when I realized that it wasn’t possible to provide a real native experience with Android; if one vendor decided to put use a bright theme in their phone, my app will look black and pretty different, or, at best, with unique action bar colors.

The way I think this should have been implemented is having some way to define masks (maybe as a new type of drawable?); it would be a bitmap image that would be treated as grayscale, and would colorize them with the current text color when rendering them; that way, the action bar icon would have the same color everywhere, and not depend on the theme.

One of the biggest complaints about android is the fragmentation, and not having even the possibility to make an application feel completely native will just keep adding to this perception.

comments powered by Disqus