Android: Nuts and Bolts III

This Nuts and Bolts is going to be relatively limited in scope; I am actually deviating from the topic I planned for the third installment. Over the past few weeks, you’ve probably seen me say something to the effect of “Google says RelativeLayout is more efficient, but I don’t really get why” several times. It has irked me that I didn’t understand it, but I didn’t really see any means of finding out, either. Today I can finally say I at least have a guess as to what they meant when they told us about this elusive inefficiency. Curious? Look behind the “Read More“!

 

Update (July 28, 2009): This post represents my attempts to solve a problem which was ultimately solved in Nuts & Bolts IV using TableLayout. I’m maintaining this post because it does offer a (somewhat) worthwhile discussion of the differences between Relative and Linear layout, and the merits of each.

After I got that pesky bit of MM taken care of today, I decided to focus my efforts on learning good layouts for Android. Thus far I’ve used exclusively RelativeLayouts, and I haven’t really put a huge amount of thought into them other than making sure things were centered, large enough to touch, and at least presented in a logical order. I decided to tackle a fairly complex UI layout as a learning experience – the following represents what I have learned so far, so take it with a grain of salt. If anyone learns that I’m incorrect about how any of this works, please email me and I will update this Nuts and Bolts.

I first built a fairly complex UI using RelativeLayouts: I have two panels (RelativeLayouts) laid out side-by-side, each one contains two TextViews and two buttons with some spacing done around everything. It took a lot of tinkering to make everything look spaced out the way I wanted; the major issue is that there seems to be no way of making a RelativeLayout take up 50% of the parent layout. I can add padding of a variety of types, but even if I specified 50% of the screen size in pixels, the whole scheme would crumble in landscape mode.

I then remembered that in Hello, LinearLayout, the various layouts do in fact take up a proportion of the screen size. Upon further investigation I learned that LinearLayout has access to android:layout_weight which can set the proportion of the layout that any given view should take up. I find it a bit unintuitive that smaller numbers seem to make the view take up more room, but this is probably due to a misinterpretation on my part of what “weight” actually means. Having established a means of separating my left panel from my right panel with even spacing and centering, I set about recreating my original layout.

Unfortunately, my original layout took many luxuries of RelativeLayout into account. I had one textview above everything, a textview to the left of my buttons, and the buttons arranged one on top of the other. LinearLayout stacks each item one after the next, in either a horizontal or vertical arrangement, so my previous layout was impossible inside a single LinearLayout. I attempted to put a RelativeLayout inside of my LinearLayout, but when adding more than one of these I came back to the problem of not being able to space everything out evenly.

Finally, a bit overwhelmed, I picked up a pen and a notepad and drew my layout using boxes. Every time I needed to arrange one element below another I encased them inside of an android_orientation=”vertical” LinearLayout. Every time I needed to arrange one element beside another I encased them inside of an android_orientation=”horizontal” LinearLayout. When all was said and done, I had 5 levels of LinearLayout nesting below the root layout which comprises the entire screen. It was at this point that I began to guess that perhaps this is why the Google folks said LinearLayout was innefficient.

My RelativeLayout required only 1 level of layout nesting below root, but was not quite centered and behaved poorly in landscape mode. My LinearLayout was dead-on, but took more work to construct and many more layers of layout nesting. If there is a better solution to the problem than what I have found, I would be very interested in it. For this evening at least, nesting LinearLayouts seems like the best way to achieve the functionality that I desire.