One thing that’s come up a few times after 1.7 has dropped is a new default configuration in Titanium that has “broken” layouts for Android applications. If you’re upgrading from previous versions of Titanium to 1.7, your layouts may seem “squished” and your fonts smaller than you expect. For the impatient or the experienced, I will share the “fix” first so you can revert Titanium back to its old behavior. For those wishing to understand how Titanium and Android handle layouts and different screen densities, I will provide some context and guidance for Android layouts second.
In previous Titanium versions, we overrode a default setting in AndroidManifest.xml which has to do with scaling UI for various screen densities. In 1.7, we stopped doing that and followed the Android defaults, empowering the developer to decide what behavior they might prefer. To change this back to the old, auto-scaling behavior, you will need to edit a setting in tiapp.xml:
Adding this to your tiapp.xml should solve any problems with layout scaling that were introduced as a result of upgrading to 1.7. You may or may not need to clean your project (force Titanium to freshly re-generate the native project files) to ensure your new configuration settings are picked up:
Supporting Multiple Screen Densities
And now a bit of context on what the above code snippet is doing.
Android devices, as you are no doubt aware, come in many shapes and sizes. For developers, that means supporting screens with different resolutions and densities – the official Android docs on supporting multiple screens is essential reading on this topic. Screen density is the number of pixels on a physical space on the screen, usually measured in dpi (dots per inch). Screen resolution is the actual number of pixels on the screen, usually given in a width by height notation like “1440×960”.
For example, I have a Motorola Droid 2 I use for development. The resolution of its display is 480×854 – it is also considered a “high density” screen (240dpi) because all of those pixels are packed into a reasonably small area. If I wanted to test this device screen size on my desktop in the emulator, I would use the “WVGA854” skin, which is available in the Run Configurations menu in Titanium Studio:
Android will ship on devices with many different screen densities, so coding our application with different pixel sizes for fonts and layouts would get old pretty fast. To help combat this, Android allows developers to specify layout values (and font sizes, though the term is slightly different) in density independent pixels, also called dips. When your UI components are sized in dips, the Android OS will scale your UI up or down as if the screen your application is running on were what it calls a “medium density” (or 160dpi) screen. Most of the time, this is the behavior we would want and expect.
To make dips the default unit for UI components in an Android application, it requires an entry in AndroidManifest.xml (android:anyDensity=”false”), which is what we specified in our tiapp.xml above.
In Titanium Mobile, typically we specify fontSize or height/width/top/bottom/left/right values as integer values. On iPhone, these values correspond to the 320×480 point system used to lay out UI components (even though the densities of iPhone handsets can be different). On Android in 1.7, raw integer values (unless the tiapp.xml configuration is changed) correspond to real pixels on the screen. Consider the following simple app.js:
On Android, on a medium density display (like the HVGA screen size in the emulator), the box and text show up at a pretty large size. On a high resolution, high density display like my Droid 2, the text and box are pretty small:
In terms of proportions, I’d prefer to have the box and text show up at about the same size on the high density screen as well. I can fix my code by specifying my heights/widths/font sizes as a ‘dp’ or ‘dip’ string rather than an integer value:
On the iOS side, that platform doesn’t care about the units – they will take any ‘dp’ values and use them as points. That code produces something which is a little closer to what I’d expect:
So when it comes to handling multiple screen densities on Android in Titanium, you have a couple of choices. In code, you can specify your height/font size values in either dips or raw pixels, as befits the situation. Or, if you’d rather have your UIs scaled up and down in all cases (as was the default setting in previous versions of Titanium), you can add the tiapp.xml configuration setting we led off this article with. Let us know if you have any questions, and hopefully this helps clear up any confusion around layout on Android.