Latest Tweets

 

Implement your own Android layouts

Here’s an android development tip: Instead of spending lots of time creating complicated layouts for your Android applications by piecing together stock layouts, just implement your own layout.

Creating a fully-featured and robust layout is a lot of work, but writing one that works well for just your application can be less work than the alternative. And unless you create a very poor implementation, it will almost certainly perform better than an alternative which nests several layouts in a complicated way. This is because the algorithm that measures views may need to backtrack, and this can become expensive as layouts become deeply nested.

Note that I’m using the word ‘layout’ here to refer to a ViewGroup that does nothing but lay out its children. This is different to a Swing layout, for example, which is not a GUI component in its own right, but instead operates through a container.

I’m posting this now because I have a good example that’s simple enough to share. In an activity that I’m currently implementing, I needed a layout that could rigidly arrange its elements into a square grid (see my previous post for the wireframe). This is impossible to enforce using any of the standard layouts, though it would be possible to mimic the behaviour with some extra messing around.

Instead I implemented my own layout, and here it is in action:

1x1 grid3x3 grid5x5 grid

This layout is a good example of a simple layout because the assumptions have been simplified:

  • the layout only deals with exact squares (can’t get much simpler than a square grid of squares)
  • the layout of the children is kept rigid (exact dimensions are specified - my application need anything else)
  • it doesn’t support gravity (it could, but again, my application doesn’t need it)
  • it doesn’t care to handle oversized Views that won’t fit the grid (due to the application, I can just guarantee it won’t happen)

Actually implementing a layout comes down to implementing two key methods:

  • onMeasure() to compute the size of itself and its children,
  • onLayout() to compute the bounds of its children for rendering

This is explained in the developer guide. There are also a few nice-to-haves that are easy to implement:

  • Basic accessors for parameterizing the layout (just remember to call requestLayout() internally when they change)
  • Support for custom XML attributes (it’s much more convenient to set parameters in the XML; there’s a good explanation on stack overflow)
  • Supplying custom layout parameters (via generateDefaultLayoutParams(), generateLayoutParams() and generateLayoutParams())

I’ve included the source code for my square grid layout below. WARNING: It has not been battle tested and as a consequence may some serious bugs, though it has been working well enough for me. The implementation is also limited by the assumptions described above.

This source code includes all the ‘nice to haves’ that I listed but remains a very simple class that is much easier to use, reuse and maintain than an alternative implementation consisting of nested layouts. It also has other benefits that aren’t as obvious, for example grouping children directly under one parent view can make some animations easier to control.

The source code listed below is in the public domain.

Now that android devices with different screen resolutions are becoming a reality, I just wanted to share these shots of Daisy Garden at QVGA.

Even though I’ve done no direct work to support QVGA in my applications, it always features in my thinking for the UI. One simple approach is to aim for two things in each activity layout:

  1. Ensure the largest component can be scaled or scrolled
  2. Keep a tight limit on the number of other components on screen.

You can see how this approach has worked quite well for Daisy Garden; this is the first time I’ve viewed the app at QVGA resolution, and though there’s definitely work to do, all the layouts look redeemable.