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.