Android: Nuts and Bolts IV could easily be titled “The Right Way To Do Android: Nuts and Bolts III”. Since writing my last entry discussing Relative versus Linear Layout, I have made an important discovery! Table Layout actually solves the problem much better than my previous hokey tinkering did. (In fact, just bookmark that page, or print it out and frame it or something, it’ll save you a lot of time.) I also learned some really cool stuff about phone orientation changes, alternate layouts, and alternate resources in general.
For a more detailed description of TableLayout and other neat stuff I’ve learned since N&B III, check behind the Read More cut.
The basic jist of a TableLayout is that you can have it work as a bunch of table rows stacked one on top of the next, with each table row containing as many cells as you want. The other alternative is to give your TableLayout an android:orientation=”vertical” property; this will set the table to use columns filled with cells and stack them left to right instead. You can then load up your table with TableRow elements, which can themselves contain multiple views/layouts.
TableRows have a number of cool properties which let you place things exactly where you’d like. First and most importantly, android:gravity will allow you to center_horizontal, center_vertical, center, right, left, etc. your objects. You can also use android:gravity on the items within your TableRows, or just within Layout elements in general. Gravity is your friend, use it! To check out some of the other neat android:properties stuff for TableRow, just load up the xml editor in Eclipse, and type android: inside of a
It is noted extensively elsewhere, but just to avoid tripping anyone up, I will warn my readers that the TableLayout will enforce automatic android:layout_height and android:layout_width restrictions on you. There are some weird cases where you can set one or the other, so feel free to try if you think things aren’t working as they should, but if you don’t see any effect from your changes this will be why. Chances are that, whatever it is you are trying to do with height/width, you can solve it with some clever margins or padding.
On a somewhat (but not entirely) unrelated sidenote, I learned about an interesting property of ScrollView: android:fillViewport=”true” will allow the ScrollView to fill the entire screen up. Otherwise, you can end up with a bunch of smooshed views inside of your ScrollView, which is pretty unnappealing. In my case, my table spans more vertical space than the screen has available, so I stuff it inside of a ScrollView to allow the user to see everything non-smooshed. This is a pretty useful technique any time you want to display virtually anything larger than the screen itself, since you can arrange to scroll horizontally or vertically as needed.
Now, on to the really tricky part! I originally got into all of this weird layout stuff for N&B 3 because my UI looked really bad when I tilted my phone horizontally and entered the landscape view. After working around in circles for a while learning about nesting LinearLayouts, then fixing all of that with a TableLayout, then still being frustrated at the way Android chose to lay out my tables in landscape, I finally came up with another solution! If only I could just write a second xml layout for landscape view, I told myself, everything would be great.
Yeah, well, turns out you can. Turns out it is really easy and super convenient. In fact, after you have learned the technique I will present, you will also be equipped to present alternative images and other resources as well as layouts. You can affect these resource changes based on a host of conditions, one of which being phone orientation. I had just a little bit of trouble making sense of exactly how all of this works, so I’ll break it down into some simple steps.
In order to present alternate resources, you create new folders with keywords in their names for the condition(s) you are coding for. All of the examples and lengthy discussion on the page I linked is there to explain what these are and the priority scheme used when multiple conditions are involved. In my case, I created a folder named layout-land. This folder will replace the files in the ‘layout’ folder when in landscape mode. One important part of this that is apparently obvious to most folks (but was not obvious to me!) is that Android will not replace the layouts for you unless you name the xml files within your new folder exactly the same as they are in your normal layout folder. That is, in order to replace main.xml when I rotate my phone horizontally, I had to create a layout named main.xml inside of my layout-land folder. I originally named it main-land.xml or something to that effect, and Android did not affect the changes when I rotated my phone.
The best approach to take with this, in my opinion, is to simply copy your main.xml (or whatever you want to change based on orientation) into your layout-land folder. From there, alter any spacing or other layout issues as needed, and Android will take care of everything else for you. The beautiful thing about your newfound knowledge of condition resource swaps, is that you are now an expert on Android Localization!
As it turns out, the exact same techniques used to change layout resources based on orientation allow you to change string resources based on phone locale. The other piece of this is the strings.xml file; remember that annoying little thing they made you do in your very first Android tutorials, where you reference a strings.xml resource containing your text instead of just coding it into your app? You can create folders named things like values-en or values-fr to create strings.xml resources with different languages contained in them! As long as you can figure out how to type your application text in a given language, you can add functionality for that region to your application. I find this to be a very cool piece of functionality, especially considering we obtain it for free in the process of learning the orientation layout swaps.
I hope that this Nuts and Bolts has been informative, as usual, this represents what I know at the time I write it, so be on the lookout for any corrections or additions in the future! Don’t worry if this post is too much to digest all at once, it represents a week or so of my toiling over Android. Thanks for reading!