Meet the Green Goblin, part 1

December 13th, 2010

Last Friday we announced a significant update to the Android Market client. A whole slew of features went into this update (and many more are to come), and this week the pixel geek in me will be talking about the new visual design of the application.

To kick off this series, let’s talk about the layouts. Traditionally, the application design breaks the screens into separate sections – headers with basic navigation controls, main content area and perhaps the footer with context-sensitive action controls. This works especially well when each section occupies a rectangular portion of the screen – with the layout managers and the painting pipeline optimized for non-overlapping rectangular views. If you follow the recent visual trends in mobile, desktop and web design, you would notice that the designers are starting to push the bounds of the underlying UI toolkits to explore richer layouts with overlapping free-form controls. A few weeks ago our designers have come up with a new approach for browsing the main market content and a richer interaction model that puts more control into the hands of the users.

As noted in the announcement, we’re using an interactive carousel that enables a much more immersive interaction with the content in both portrait and landscape mode. In portrait mode, the list of featured applications “disappears” below the carousel, while in landscape mode the list is placed to the right of the carousel. Once the list starts scrolling, it goes below the carousel – with the row contents still partially visible in the left and right “ears”. If you were to open this activity in the hierarchy viewer, you would see two overlapping top-level views:

The carousel and the list overlap in the area that “contains” the curved bottom edge of the carousel. Without this overlap the topmost visible row in the list would be clipped at the bottom-most point of the arc with very noticeable white areas in the left and right ears of the carousel. While the core layout classes support a wide variety of cases, you’ll need to write a custom layout in case you have overlapping child views. Here is what you need to keep in mind:

  • You can extend an existing core class, such as LinearLayout. It depends on how much tweaking you need to do after the base class does its magic.
  • The LayoutParams defined in ViewGroup class supports a very rudimentary set of attributes (width and height). You can extend the LayoutParams class and add your own attributes (in much the same way the LinearLayout does, for instance). Add an attribute definition in your res/attrs.xml, enumerating all possible values and a declare-styleable entity with your custom atribute(s). Then, define a Java class with static ints that correspond to the attribute values. Then, extend one of the core LayoutParams classes (depends what exactly you need from the core) and get the values for your custom attributes. Finally, override the generateLayoutParams method in your container to return an instance of your layout params class. When you need the actual attribute value at runtime, cast the result of getLayoutParams of the specific child view to your custom class and you’re good to go.
  • In your custom layout, implement both onMeasure and onLayout. Make sure that the final width and height that you set in child.layout inĀ onLayout match the measured width and height that you pass to child.measure in onMeasure. In case you see incorrect bounds of grand-child views, open the hierarchy viewer and compare the actual and measured values for width / height.
  • If child views overlap, you most probably want to have some kind of transparency or translucency in the overlapping area. The child views are painted in the order that is defined in the layout XML. In our case, we want the list view to be drawn before the carousel – otherwise the topmost visible row will be painted on top of the bottom curved edge of the carousel. This means that you will have some degree of coupling between the XML layout definition and the measure / layout code.

Let’s take another look at the overlapping area. As you can see, the list has a “Featured” header row. This is a simple text view with a light gray background. However, there is one very important usability setting on this header view – the top padding. As noted before, the top edge of the list is above the bottom-most point of the curved arc. If we don’t set any top padding on this list header, its text will be partially obscured by the carousel curve resulting in a very poor UI experience. The question is how do we compute the top padding?

The actual value depends on the pixel size of the screen. Remember that there’s a whole bunch of different devices out there, and you cannot make any assumptions about the screen hardware – physical size, pixel size or density. This is directly related to our curved carousel – the curvature radius and, by extension, the vertical size of the overlap area are only known at runtime.

If we were to define the overlap area height to be, say, 30 units (density-independent pixels), the arc would have different perceived curvature across devices such as G1, Nexus and Samsung Tab. If you target a “common” hardware such as Nexus / Droid / EVO, you will end up with an arc that looks too steep on a G1 and too shallow on a Tab. So, instead of hard-coding the overlap area height – and by extension the curvature radius – at design time, we compute it at runtime as the function of the actual pixel size of the screen.

This overlap area height is then used for two purposes. First, it defines the measured and actual height of the carousel and list view. If you were to add the two heights and subtract the overlap height, you would end up with the exact height of the screen. Second, we set it as the top padding on the list header view. This effectively pushes down the label so that it is fully visible (remember that you cannot rely that the text is short if your app is localized), with an extra bonus of extending the light gray background all the way to the carousel arc ears.

Up until now we talked about the portrait mode. What about the landscape?

Here, the design places the carousel and the list side by side in order to better reuse the available screen estate (more on this in tomorrow’s episode). All of the points mentioned for the portrait are relevant here, modulo the following:

  • The arc curvature and overlap amount are based on the screen width.
  • The overlap is along the X axis, with both views spanning the full height of the parent.
  • Each list row has a custom left padding that is based on the overlap area width. This prevents the app icons from being partially obscured by the right curved arc.
  • The same padding is set on the list header view.
  • If we were to set the padding on the list itself, we wouldn’t be able to have the header view background and list separators extending all the way to the left and below the carousel. The UI would be usable, but uglier.

This is it for today. The next entry talks about the landscape orientation and how the design aims to use the available screen estate without cramming too many visual elements.

Design, uninterrupted #111

December 9th, 2010

Today’s post highlights the design of BottlerocketCreative.com. An attractive single-page design features a strong balance around the center vertical axis, clean typography with a number of embedded fonts and noise textures that help break the monotonicity of large dark header and footer sections. Light sepia is used throughout the main section for background, decorative elements and text styling.

Note how the desaturated red from the main logo is used sparingly for the two contact links and the follow-me-on-Twitter link in the footer. Also note the simple yet effective drop-shadow rollover effects on the portfolio thumbnails and the off-by-one translucent text shadow around the text sections to improve readability.

Food for thought

December 9th, 2010

Engineers who insist on doing everything themselves underestimate the talent and skill needed to succeed in other domains, and thus also shortchange their own ideas and ambitions. Designers who refuse to interface with the technical side of things, both in using and harnessing some amount of technical knowledge to understand the limits and possibilities of product, or in using engineers to design products (solutions) to fit needs (problems), miss out on opportunities to create the most effective products possible.

From “On designers in Silicon Valley” by Nina Khosla.

Design, uninterrupted #110

December 8th, 2010

Today’s post highlights the design of Panoetic.com. When first loaded, the site has two main sections – a three-row interactive portfolio and a selection of client logos. The portfolio features a number of attractive transitions – from rollover and (delayed) rollaway effects to the overlay slideshow of the specific project on clicking a thumbnail. Note how each successive row features more thumbnails (three to four to six) while maintaining the same overall vertical grid. The client logo section is placed on the background of earthen brown, with each logo colorized in the desaturated pink-to-yellow browns, creating the effect of the portfolio thumbnails “growing” from the client seeds planted in the ground.

The header section continues the vintage theme set by the background color palette of desaturated blues, browns and off white by interleaving a few intricate illustrations with the floral background patterns. Each illustration (two ribbons and the upward-pointing hand) is an action area that reveals hidden content above the header section. If you position the mouse over the charcoal-painted hand and click three times, the entire content will reveal three sections that provide further information on the agency itself and the people behind it. The vintage decoration elements are present throughout these extra sections, with additional usage of strong orange color to highlight the main action items (expanders, twitter links and the submit button of the contact form).

Finally, note the usage of embedded Felt Tip Roman and Salsbury for various headers and subheaders – both hand-written fonts that further reinforce the vintage theme of the site design.