Image and graphics tips for Android

This article provides some practical tips to help you achieve the best visual quality on all devices for your Android app.
The look of your app is important. For users, it's the first quality indicator they see. Attractive design, clear and effective layouts that feel optimal on the user's device, and high quality icons, graphics, and images, send clear quality messages.
Visual quality also contributes to both the functionality and usability of your app. For example, legible fonts and font sizes, and colour palettes that enhance legibility, are functionally essential, not just nice-to-haves.

The importance of consistency and scalability

The biggest issue affecting how an Android app looks on a given device is scaling. Compared to some platforms (for example iOS and Blackberry), the variation in physical display characteristics between devices based on the same or compatible Android software versions, can be much greater. Android solves this problem by applying a scaling model to your app's UI layouts and graphic resources. To achieve consistent quality on all devices, you need to ensure that your app scales correctly.

Scaling on Android

Android implements a simple display abstraction model that enables it to scale UI layouts and resources at runtime, to fit the wide range of different physical displays found on Android devices.
Android generalises device displays into categories based on two parameters:
  • Screen size, the physical size of the display (measured diagonally)
  • Screen density, the physical pixel density of the display (in pixels-per-inch, or ppi)

Screen size

Android defines four generalised screen sizes:
Qualifier Size
small ~3 inches (approx)
normal ~4 inches (approx)
large Exceeds 4 inches
xlarge Exceeds 7 inches
  • Most phones are classified as small or normal (roughly 3 to 4 inches diagonally)
  • A small tablet like the Samsung Galaxy Tab is classified as large (larger than 4 inches)
  • Extra-large applies to large devices, for example large tablets
Android defines four generalised screen densities:
Qualifier Description Nominal value
ldpi low density 120 ppi
mdpi medium density 160 ppi
hdpi high density 240 ppi
xhdpi extra high density 320 ppi

Size approximations

Although size and density are technically unrelated, in practice Android relativises screen size to pixel density and resolution (the pixel dimensions of the display).
Use the table below as a ready-reckoner to map devices by resolution and actual density to their Android approximations:
Size Android approximations
dpi mdpi hdpi
Small QVGA low ppi - VGA high ppi
Normal WQVGA low ppi HVGA medium ppi WVGA high ppi
Large - VGA, WVGA medium ppi -
Extra large - SVGA medium ppi HVGA high ppi

Supporting scaling

To support the scaling model, Android allows you provide size- and density-specific resources for your app.
Typically:
  • screen size has most impact on your app layouts
  • screen density has most impact on your image and graphic resources
If your app makes extensive (or critical) use of images or other bitmap-based graphics, it's important to understand the impact that different screen densities will have on your app—Tip 1.
Except for tablets, you can mostly assume a normal layout will scale successfully, so long as you follow the guidelines, specify relative layouts, and use Android's "virtual pixel" units—see Tip 2.
Android also makes it easy to customise layouts for device orientation in a similar way.

A note on Android versions

Android 2.2 (Froyo) and 2.3 (Gingerbread) are the versions in most common use on current handsets from Vodafone. Android 3.x specifically targets tablets, and Android 4.x is not yet widely available. This article therefore concentrates on Android 2.x.
Note that some details of the way Android scales app resources change in 3.x to improve look and feel on tablets. Those changes are not covered here.
Android manages API evolution and compatibility by labelling release versions with API levels. In general, API evolution is always additive, and compatibility is always retained going forwards i.e. an Android 2.3 device (level 9 or 10) supports all Android 2.1 APIs (level 7).
To target current Android phones available on Vodafone, set your build target API level to 7 or 8. Level 7, for example, is Android 2.1 (Eclair). While most current Vodafone phones run later software, some HTC Desire owners may be running Eclair, even though the device supports upgrading to Android 2.2 (Froyo, API level 8).
Recent Android platforms include:
Android release API level Release name
Android 4.0 14 Ice Cream Sandwich
Android 3.x (Tablet specific) 11, 12, 13 Honeycomb
Android 2.3 9, 10 Gingerbread
Android 2.2 8 Froyo
Android 2.1 7 Eclair

App requirements

There is only one formal graphical requirement for an Android app:
  • An app icon (i.e. the Launcher icon) is required
However, we recommend you add the following informal requirements to your project checklist:
  • Plan, support, and test for scalable UI design, including icons, images, and all other graphical elements—see Tip 1, Tip 2, Tip 4, Tip 5, Tip 6, Tip 7
  • Use appropriate graphic and image file formats, and balance image quality against file size when creating the graphics for your app—see Tip 3
  • Test for legibility. Text sizes, text styles, and text colour/background colour combinations should maximise legibility in outdoor daylight conditions as well as indoors—see Tip 8
  • Test for accessibility. Design your app colour palette and app text to support all users including those with colour vision impairments (around 1 in 10 of us!), and near-sightedness (as many as 1 in 3 of us!)—see Tip 9
Of course, as well as your Launcher icon, you must supply icons for menus, the status bar, tabs, dialogs, and list views, depending on your app.

Using images and graphics on Android

Looking consistently good on all Android devices is an important quality.
The following tips will help you optimise your app graphics and images for a range of Android devices.

Tip 1—Provide size- and density-specific resources

When Android loads your app, it queries the device for its size and density.
If you supply size- and density-specific resources (e.g. layouts and images), Android loads them without scaling, except for image scaling you define in your layout, for example using android:scaleType on an ImageView element in a layout:
<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:src="@drawable/fw2_studio"
   android:scaleType="center"
   />
If you don't supply size- and density-specific resources, Android attempts a best match from the nearest, smaller/lower size/density resources and scales up.
A well-designed layout will scale well, but scaling up images causes immediate loss of quality. As far as possible, avoid ever scaling up images.
Follow Android's resource directory structure and naming conventions to provide display size- and density-specific resources.
For example, for layouts, in your MyProject project folder provide:
MyProject/
    res/
        layout/
            mylayout.xml // Default layout for normal screen
        layout-small/
            mylayout.xml // Layout for small screen
        layout-large/
            mylayout.xml // Layout for large screen
        layout-large-land/
            mylayout.xml // Layout for large screen landscape
        layout-xlarge/
            mylayout.xml // Layout for extra-large screen
        layout-xlarge-land/
            mylayout.xml // Layout for extra-large screen landscape
This assumes that for most layouts, Android's auto-rotation and scaling adjustments, work fine; but that for large and extra-large devices, a custom layout makes better use of the available display.
  • On normal screens layout/mylayout.xml will be loaded, and Android will auto-rotate and adjust scaling for portrait/landscape orientation changes
  • On small screens layout-small/mylayout.xml will be loaded with auto-rotation
  • On large and extra-large screens layout-large/mylayout.xml and layout-xlarge/mylayout.xml, respectively, will be loaded in portrait mode, and layout-large-land/mylayout.xml and layout-xlarge-land/mylayout.xml, respectively, will be loaded in landscape mode
If your app makes significant use of images, always provide density-specific resources to ensure that image scaling works appropriately for your app across the range of different devices.
Note: You may not need to support every density with custom images; images too big to display complete on a lower density device but set to android:scaleType="center" in your layout, will be cropped but not scaled.

Above from left to right: Image 540 x 360 scaled on a 320 x 480 device; the same image cropped on the same device
in portrait and landscape modes
Also, supply custom bitmap image files for icons and the other graphical elements of your UI, for some or all device densities.
Store images and graphics in a resources directory that uses a density qualifier, for example for high density use res/drawable-hdpi/, and so on. If you omit the qualifier, this folder will be used by default for mdpi screens, and scaled for other densities that you don't explicitly support.
For images and graphics:
MyProject/
    res/
        ... // Layouts as shown above
 
        drawable-ldpi/
     ... // Image files
        drawable-mdpi/
     ... // Image files
        drawable-hdpi/
     ... // Image files
        drawable-xhdpi/
     ... // Image files
        drawable-nodpi/
     ... // Image files
In case you want an image never to be scaled, place it in a drawable-nodpi directory, but test carefully to ensure that the result works on all sizes/densities.

Tip 2—Use relative layouts, dp, sp, and mm

To support its scaling model, Android defines two "virtual" pixel units, which are scaled relative to the nominal density of the device display:
  • dp units - device independent pixels normalised to 1 physical pixel on a 160 ppi screen i.e. medium density. Scaled at runtime. Use for screen element dimensions
  • sp units - scaled pixels, specified as floating point values, based on dp units but additionally scaled for the user's font-size preference setting. Scaled at runtime. Use for font sizes
Note: In practice, there is little support for system-wide user preference setting of font sizes in most available devices. You should still use sp units, though, to be compatible with future devices that may support it.
For example, the Android documentation gives the example of setting layout_width="100dp" enabling you to calculate all remaining values in your layout relative to 100 (full width).
In some cases, for example when specifying button sizes, it may make sense to use mm (millimetre) units to ensure that screen elements always retain the same physical size regardless of display size or density.
In addition, you should always use RelativeLayout for layouts; AbsoluteLayout is deprecated and should not be used.

Tip 3—Use appropriate image formats - PNG versus JPEG

Android "prefers" PNG for bitmap image files, "accepts" JPEG, and "discourages" GIF.
However, PNG and JPEG are not equivalents. They have different quality trade offs, and PNG is not always best:
  • JPEG can offer up to 50% file-size reductions over PNG, which is significant if your app is image-intensive
  • A higher quality "lossy" JPEG may look better than a highly compressed "lossless" PNG, for the same file size
Both formats are useful, both have strengths and weaknesses:
PNG JPEG
lossless lossy
bigger file size smaller file size
YES transparency NO transparency
Typically use for: Typically use for:
icons, simple artwork, line drawings, text-heavy, few colours, flat colours photographs, "realistic" images, complex images, many colours, colour gradients
Android also supports additional formats including stretchable "nine patch" PNGs, see Find out more, below.

Tip 4—Add labels to your images and graphics for debugging

When developing and debugging, if you use size-/density-specific resources, add visible size/density labels into your debug graphics, so you can see immediately which resources have been loaded.

Using labelled images for debugging, you always know exactly which resources Android is using

Tip 5—Use the supports-screens element

From Android 1.6 (API level 4), the supports-screens element in AndroidManifest.xml enables you to specify which screens your app layout supports. On supported screens, Android scales the UI and resources - based on the resources you supply, see Tip 1.
When your app runs on an unsupported screen (one you didn't specify), Android drops into compatibility mode, and instead of scaling, displays the nearest-smaller layout that fits, with no scaling. Compatibility mode displays a "postage stamp" version of your app, bordered with black. You should aim to avoid this.
The possible attributes/values for supports-screens are:
Value Description Default
android:smallScreens Support smaller aspect ratio than the "normal" (traditional HVGA) screen true
android:normalScreens Support "normal" screen form-factors e.g. HVGA medium density, WQVGA low density, and WVGA high density true
android:largeScreens Support screen "significantly larger" than "normal" -
android:xlargeScreens Introduced in API level 9. To target currently available Vodafone phones, you can ignore this -
android:resizeable Deprecated from Android 1.6 true
The default values for small and normal screen support are true, and it's safe to assume the defaults without explicitly setting either value. (Never set either false.)
Because the default value of android:largeScreens varies between versions, always set this true to avoid your app being run in compatibility mode. To do so, add the following statement to AndroidManifest.xml:
<supports-screens android:largeScreens="true" />
Never set this false. Doing so enables screen compatibility mode when your app runs on large screen devices.
Alternatively, to also support both large and extra-large screens, instead add the following:
<supports-screens android:largeScreens="true"
                  android:xlargeScreens="true" />
Don't use android:resizeable, which is deprecated from Android 1.6 (and in particular, never set android:resizeable="false").

Tip 6—Configure your emulators with real device values

Conventionally, desktop systems display at 72ppi (Mac), or 96ppi (Windows, Linux). Compared with mobile, desktop displays are always low density.
Always configure your Android emulators to mimic real device values, and always set them to scale to emulate device density.
In Eclipse, it's easy to create multiple emulators (from the Eclipse menu bar, select Window > AVD Manager > New) configured with values for real devices:
  • Name the emulator for the real device it's emulating
  • Specify Resolution, don't use Built-in generic sizes
  • Set the device density to match the real device (in the Hardware pane set Abstracted LCD Property to the real density, always an integer value)

Settings for Xperia Mini Pro "Mango"
Confirm the settings after the emulator has been created by highlighting in the Virtual Device Manager window, and selecting Details.
When you launch the device, always select Scale display to real size, and type in the real screen dimension in inches.

Always scale for the real device size
Configured correctly, the emulator will load the correct screen density-dependent resources, see Tip 1.
If you don't set the device density, the emulator defaults to low density, and always loads ldpi-specific resources. Resolution (pixel dimensions) will be correct, but your density-dependent image resources will not display as intended.
Of course, nothing you do will reproduce higher density image quality on a lower density desktop display.

Tip 7—Use real devices in your design/test cycle

It's essential to validate on real devices that your layouts and screen-/density-specific resources behave as you intend. It's also important to validate your app's behaviour on devices with screens you don't support with size-/density-specific resources, and verify that your app looks and behaves acceptably under Android defaults.

The real-time display is a video image, so live quality is variable:

Running remotely using the Vodafone Handset Cloud on Perfecto
Use the snapshot feature to save device screen dumps to your Perfecto account. At the end of your session, download the image files for detailed study. Quality is identical to that of local screendumps from a real device (e.g. via DDMS).

Tip 8—Design daylight-aware and power-aware colour palettes

Astonishing but true. Light pixels are more power hungry than dark pixels on active matrix displays e.g. active-matrix LCD and AMOLED. Display technologies differ widely between vendors and devices, but power usage should definitely be part of your colour palette design decisions.
Another parameter in your palette design should be readability in outdoor daylight conditions, as well as indoors.
Always test your app in a range of lighting conditions, to simulate the conditions in which your real users will use your app.
Some useful observations are:
  • Very dark (e.g. black) backgrounds make reflection problems worse in direct light
  • Very light (e.g. white) backgrounds use significantly more power on active displays e.g. AMOLED
  • White text is "starey" and quickly becomes tiring to read
  • Fully saturated, pure colours "shout" and quickly become tiring to look at
  • Blue and blue-tinted backgrounds can merge into sky reflections outdoors
Take your app colour design seriously. Colour, and colour theory, is a well-studied topic—what we think of as the "modern" colour sphere, as found in your favourite paint application, dates back to the early 1800s.

Tip 9—Design for all your users

A further point to make about your app's visual design is that anything up to 10% of the (male) population may have problems distinguishing red from green, and that as many people wear glasses (or contact lenses) as don't.
  • Design for legibility and choose defaults that work for the largest possible number of users
  • Design flexibly and offer larger font layouts, or custom settings, if your app is text-heavy, or just text-critical
Note: As noted in Tip 1, system-wide user preference setting of font sizes is not well supported on current Android devices.

Find out more

Although not app specific, Stephen Few's book Information Dashboard Design (O'Reilly) is an easy read, designed for practitioners, useful, and relevant to app developers. Otto Runge, by the way, published his work on the colour sphere in 1809.
For full details of Android releases and API levels, see the API levels guide.
The Android developer site has excellent resources on scaling and supporting multiple screens, the supports-screens element, layouts, and bitmap resource formats, including "stretchable" nine-patch PNGs (see also the comments on Android build-time optimisation of PNGs, and in special cases, how to avoid it).
The PNG vs JPEG debate usually takes place in a web usage context, but similar considerations apply to apps.

The table below lists some examples of current Vodafone phones. Note that although Galaxy Tab is a tablet, it is based on Android 2.2 (Froyo).
Device Android release / upgrade (where applicable) Size/Type Pixel resolution Density
Samsung Galaxy Mini v2.2 (Froyo) / v2.3 (Gingerbead) 3.2" TFT (256k cols) QVGA 240x320 127 ppi
Sony Ericsson Xperia Mini Pro v2.3 (Gingerbread) / v4.0 3" LED backlit LCD (16M cols) HVGA 320x480 192 ppi
HTC Desire v2.1 (Eclair) / v2.2 (Froyo) 3.7" AMOLED (16M cols) WVGA 480x800 252 ppi
HTC Sensation v2.3 (Gingerbread) 4.3" S-LCD (16M cols) QHD 540x960 256 ppi
Samsung Galaxy Tab v2.2 (Froyo) 7.0" TFT-LCD (16M cols) WSVGA 1024x600 170 ppi

Comments

Popular posts from this blog

How to draw an overlay on a SurfaceView used by Camera on Android?

Create EditText with dropdown in android

Android TCP Connection Chat application