Introducing the Android UI Utilities project (beta)

About a month ago, I tweeted a link to a teaser video that showed off an Android icon generation tool I was building. The goal of the tool was to simplify Android icon creation for developers that don’t have access to design resources.

Today, I’m happy to make this and a few other tools available as part of the new Android UI Utilities open source project. Included are the Android Asset Studio, a set of Android UI prototyping stencils for the very awesome Pencil GUI prototyping software, and some Photoshop icon templates.

You can read more about the project and the currently available tools at the project site on Google Code. Here’s a demo video showing what kind of prototyping and asset generation you can now do:

And here’s a quick screenshot of the currently available UI prototyping stencils:

 

Now, I’ll warn that the tools are very much in beta, so they may not yet be ready for prime-time. I’m relying on you, Android developers, to test out these tools and file bugs and feature requests.

Other tools such as XML and 9-patch generators, as well as more stencils, are planned. If you’ve got ideas on what to add, you can let me know in the comments, file a feature request, or even contribute some code. I’m looking forward to expanding this project in the future to help make UI design on Android easier!

Pixel-perfect Android web UIs

Pixel-perfect Android web UIs

STOP! As of February 2013, this article is out of date. target-densitydpi is being deprecated and you shouldn’t use it. For more, see Pete LePage’s blog post on the topic.

Check out Targeting the iPhone 4 Retina Display with CSS3 Media Queries, an article discussing this same topic as it relates to the iPhone 4’s Retina Display.

If you’ve written Android SDK apps recently, you’re probably aware of the framework’s support for multiple screen densities using resource directory qualifiers. That is, you can create icons or button 9-patches at different pixel resolutions, stick them in the corresponding res/drawable-hdpi, res/drawable-mdpi, and res/drawable-ldpi directories, and the framework will, at runtime, choose which of the three graphic assets to display on a given device. The end result is a UI element that’s roughly the same physical size on every device, rendered in all its pixel-perfect glory. No blurry edges, no resampling artifacts… just the pixels, exactly as they were crafted by the designer.

But what about mobile web apps? Or WebViews in Android SDK apps? How do we get them to be pixel-perfect on all devices?

Fortunately, the aforementioned resource selection behavior can be achieved in the Android browser using CSS3 media queries and the viewport meta tag. In this post, we’ll take a closer look at what this entails.

A simple example

The rest of the post will follow a simple example user interface: a button in the middle of a blank page. In the spirit of instant gratification, here’s a link to the demo and its source code…

…and some screenshots of the demo page running in the Android browser, on medium and high density screens:

Browser screenshot comparison
Figure 1: Demo screenshots on medium and high density screens

The middle screenshot shows what the page would look like without the optimizations described in this article.

NOTE: the high dithering in the image is just to keep file sizes down; the original screenshots were far less dithered.

CSS3 media queries and target-densitydpi to the rescue

So let’s dive into the gory details. The most interesting part is the “ of index.html:

<link rel="stylesheet" href="css/all.css">
<link rel="stylesheet" href="css/mdpi.css"
  media="only screen
         and (-webkit-max-device-pixel-ratio:1.0)
         and (max-device-width:480px)">
<link rel="stylesheet" href="css/hdpi.css"
  media="only screen
         and (-webkit-min-device-pixel-ratio:1.5)">
<meta name="viewport"
  content="user-scalable=no,
           width=device-width,
           target-densitydpi=device-dpi">

Let’s go through this line-by-line:

  1. We include all.css as our baseline stylesheet. Nothing special here, moving on…

  2. We then include mdpi.css, which defines button dimensions and associates them with medium density border-images for various button states. For example, on medium density screens, we want buttons to be 48 pixels tall.

    Using media queries, we limit this stylesheet to browsers that match the following constraints:

    • Only desktop web browsers and full-HTML mobile browsers (using the ‘screen’ media type)
    • Screens that have a maximum of a 1.0 CSS px/device px ratio (see this post on the Surfin’ Safari blog for discussion of CSS pixels vs. device pixels)
    • Devices that are at most 480 pixels ‘wide’—pretty much meaning mobile devices only. This is kind of a hack.
  3. We also include hdpi.css, which has the same structure as mdpi.css but references high density button images and dimensions. For example, on high density screens, we want buttons to be 72 pixels tall (48 × 1.5).

    We again use media queries to limit this stylesheet to full-HTML browsers and screens that have a minimum CSS/device pixel ratio of 1.5. The 1.5 scaling factor for dimensions and images is because on Android, the framework treats medium density screens as 160 ppi and high density screens as 240 ppi (160 × 1.5).

  4. Lastly, we use to configure the viewport for our app within the browser. More specifically we tell the browser that:

    • Users shouldn’t be allowed zoom the app—just as we probably don’t want users to zoom a native Android app UI
    • The number of horizontal pixels in our UI is exactly the width of the device screen (otherwise there would be scaling and thus loss of pixel-precision)
    • Most importantly, using target-densitydpi=device-dpi, we tell the browser that the site is prepared to manually adapt its UI to any pixel ratio, and that no density-related scaling should occur. This is newly supported in Android 2.0, and is discussed in further detail in the WebView documentation and in this blog post by Dan Fabulich.

And that’s it! The rest of the process is making sure your CSS dimensions are correct in mdpi.css, hdpi.css, and potentially ldpi.css if you choose to support it. It’s obviously also important to provide properly sized image assets. Here’s an example of the ‘normal’ button state image from the demo:

btn_default_normal.png
Figure 2: btn_default_normal.png in the mdpi and hdpi image folders.

Parting words

On Android alone, high density screens now account for over 50% of all devices, as of August 2nd, 2010. The iOS world is now in a similar boat with the iPhone 4, which sports a 326 ppi display. This means that if you’re making mobile web apps, a very large percentage of your users are now running high density screens. If your site or app isn’t properly optimized, you may not be delivering the most beautiful experience to your users.

However, if you start implementing some of the techniques described in the post and linked articles above, you can help make a prettier, more pixel-perfect mobile web.

Thanks for reading!

Why you don’t really want a WYSIWYG layout editor for Android

Why you don't really want a WYSIWYG layout editor for Android

DISCLAIMER: I’m on the Android team at Google. The views expressed in this post are mine alone and not those of my employer.

One of the major complaints about Android development is that the layout preview tool in the ADT plugin for Eclipse lacks true WYSIWYG editing capabilities. Critics think that it’s difficult to write layout XML by hand, and that this results in poor user interfaces in Android apps. Well, I think all that talk is rubbish… and short-sighted. Sure, it’s easier to drag and drop buttons next to each other rather than having to first define a LinearLayout or RelativeLayout, but there are a number of problems with this. And, as the history of another popular subfield of UI design has indicated, designing by code and by hand, will win in the end.

What’s wrong with visual layout tools?

The inherent problem with WYSIWYG layout tools for Android stems from the variation in user interface components across devices. Android is intended and designed to run on a plethora of devices, with a variety of screen sizes, screen densities, natural orientations (portrait, landscape), and available user input methods (trackball, D-pad, touchscreen). Visual layout editors will inherently bias the UI designer toward one such configuration. Even with blatantly obvious and beckoning configuration selection controls, a layout editor restricts the designer’s field of view to just one permutation at a time. Given that there are already thousands of such permutations across Android’s current 60+ devices, this doesn’t really scale.

Visual layout editors arguably also place a lot of emphasis on the aesthetics, rather than on logical definition and structure of the UI. Even though some users may claim otherwise, a user-friendly UI is first a comprehensible one (implying an emphasis on logic and rationality), and maybe then an aesthetically-pleasing one. It must first and foremost make sense to its users by evoking a coherent and unambiguous conceptual model1. Beauty in user interface design should be a by-product of a great solution to a content interaction problem, not the other way around. Focusing on logical placement and layout of UI elements should be priority #1… only after this exercise is complete should the design focus shift to adherence to good visual design principles.

A brief detour

Consider for a moment the multi-decade-old field of web design. Ask any world class, modern day web designer what tools they use. Not one of them will answer with Adobe Dreamweaver or some other WYSIWYG tool. If they’re using Dreamweaver, it’s likely they’re spending more time in the Code view than in the Design view. You’re more likely to hear responses including pencil & paper, Photoshop, Fireworks, OmniGraffle, Visio, Coda, TextMate, Notepad (or the ++ variety), etc. These tools fall fairly unambiguously into either the pure visual design, information design, or code editing categories.

But it wasn’t always like that. Back in the late 90’s and early 2000’s, WYSIWYG tools such as Dreamweaver, HoTMetaL, Microsoft FrontPage, were all the rage and visual editing was seen as a must-have feature. However, at the same time, no one really thought much about accessibility (WAI-ARIA), standards-compliance, graceful degradation, browser compatibility, document semantics, latency, network optimization, et cetera. It’s no secret that the WYSIWYG tools were partly to blame for the overall poor quality and flexibility of the underlying markup plaguing the web. It was, and still is, simply too difficult to make a visual, markup-generating tool that does all these things right while maintaining interactive freedom and simplicity in its own UI. To date, and to my knowledge, Dreamweaver is the only tool that’s really survived—largely because of its innovation in addressing many of these areas. Nevertheless, Dreamweaver still doesn’t get you all the way there, and can prove to be more a burden than an aid. For that reason, many designers and developers choose to hand-write their HTML these days.

There are similar areas of growing importance in Android user interface design. Accessibility, localization, layout performance optimization, and device independence are not things that Android designers and developers can afford to ignore. The breadth of device types and user demographics is large, and growing every day.

So what is the solution?

Well first, I’m not saying the current state of layout design on Android is sufficient. It definitely isn’t, as many Android apps in practice suffer from poor user interface design. I’d attribute this to the complexity of the layout framework, the lack of a good set of ‘defaults,’ and also the relative inexperience with the Android layout system in the design and developer communities. Something clearly needs to be done to improve this.

Unfortunately, there isn’t a silver bullet—there isn’t a single thing that’ll just kill the issue entirely. However, there are a lot of ways this can, and will, improve. The formation of a strong community around web design exponentially improved the quality of web sites and web apps. I think the same can, and should, happen with Android. Such a community can help to grow the wealth of knowledge and resources available to newcomers. The good news is that two such communities are currently forming on Stack Overflow and the User Interface Stack Exchange. I strongly encourage you to participate!

It’s also up to the Android framework and documentation maintainers—we at Google and the carrier and OEM stakeholders—to seed the community with great resources and articles that both clarify and formalize Android UI best practices and patterns. Several resources to this effect exist now2, and this is going to get better over time.

One specific type of resource I’d like to see (and maybe work on myself) is a set of layout templates that address some common UI tasks. Such a layout template library could help take the guesswork out of correct approaches for common tasks, as well as provide UI designers and developers with a set of sensible defaults that’ll server as better starting points than a simple, blank XML document.

All in all…

As more developers and designers start working with the platform, fueled by the growing numbers of end users activating Android devices, ad-hoc resources and tools will arise naturally and will make things easier for others. Coupled with the continued investment of Android framework stakeholders, barriers to code-driven layout design will be broken, and app UIs on Android are going to get really, really good… I’m confident about that. It’s really just a matter of time.

Thanks for reading! If you’ve got thoughts on the subject, and especially if you emphatically disagree, I’d love to discuss in the comments!


UPDATE: also make sure to read Reto's great counter-post: Why You Might Want A WYSIWYG Layout Editor for Android.


1For more on conceptual models and usability, see The Design of Everyday Things, an absolute must-read, by Donald Norman.

2A small selection of currently available resources on the subject is shown below:

Good design is as little design as possible.