Understanding Titanium Views

Three years ago, the screens for the iPhone and the iPod Touch had exactly the same dimensions. On Android, with different manufacturers, there was always room for surprises, but all in all, you could pretty much anticipate the most popular screen dimensions. Today the story is completely different. Since the iPhone 5, the iPhone now has a larger screen, and at the same time you can’t forget about people who still have older iPhones. Then the iPads, the Samsung Galaxy Note and the Android tablets. Designing your app is now more challenging than ever.
If you look at iOS 7 and Android >= 4.0, you’ll notice that while they are different, there’s one important thing they have in common: their user interface is flat. This is a good thing for you as an app designer/developer because it sets the ground to building stretchable user interfaces. Flat design doesn’t have to be boring, as you can see here, and there’s a few simple guidelines you should follow:

  • Avoid using images as backgrounds : An image by definition has a fixed size, and depending on the image and the scenario, stretching it to fit will make your app look bad. There are tricks to work around this. Read more here.
  • Avoid using absolute values : Percentages should be used as much as possible. Try to avoid using absolute values to specify size and position
  • Try to anchor your design to the edges : The user interface should be conceived like a set of flexible boxes that will rearrange automatically based on the screen size
  • Don’t force the user to use your app in a specific orientation : Although there are exceptions, most of the times there is no reason for locking your app to a portrait orientation

  • Embrace tablets : Tablets have much more screen real-estate. Use it to your favor

Working out these details may sound like a daunting task, but it’s really not that difficult once you understand that:

  • Building the UI in Titanium is simply stacking stretchable boxes vertically or horizontally
  • Each box is like a piece of a puzzle
  • Boxes have to always be anchored to something, either the edges of the screen or another box

In Titanium, these boxes are called Views and are possibly the single most important UI component you should learn to use. Views have five very important characteristics:

  • They can stretch vertically
  • They can stretch horizontally
  • They can adjust their size based on their content
  • They can automatically center their children
  • The can be nested (Views inside Views)

Building a flexible user interface

Let’s build a simple UI that can automatically adjust to the screen size and orientation. I’m including a full project you can fork and play with.

The first thing we need to do is step back and see how we can divide this into boxes within boxes. Using the three centered buttons as a guide, realizing that they are centered, I’ll divide the screen into three main boxes. This screen will have its layout property set to “vertical”. Vertical layout will cause all children to be automatically stacked from top to bottom; “horizontal” does the same from left to right. The total screen size is 100%, so each box will have a height of 33.3%.

The top box is easy. It only has a Label object, and if you drop an object inside a View that has layout=absolute (the default), said object will be automatically centered; and that’s pretty handy.

Now the center box, the one with the buttons, will require some additional cleverness, but it’s not difficult.

What we’ll do is add a top level container (also a View) that we’ll call buttonscontainer. This new container will have three buttons; sounds familiar? Our main layout is also a vertical box (the screen) with three boxes, so our strategy is the same: buttonscontainer is now our new 100%. We now add three new Views that well call buttonwrapper, to which we will add the buttons. Just like before, leaving the layout property untouched will cause children to be centered, so our buttons are good to go. For the buttons we will use the top, right, bottom and left properties to apply some padding around them.

Handling changes on screen orientation

The above operations effectively gave us a UI that will adjust properly on iOS and Android, but look what happens when we rotate the phone to the landscape position.

Since in landscape position the screen has more width than height, we lost our proportions, so 33.3% is really not that much. To handle this scenario we have to go to the code. There are two things you need to listen for: when the user has changed orientation, and what’s the orientation of the device when the app starts. The code is simple:

// these constants are for convenience and readability
// get startup orientation
    console.log("Startup Orientation: " + e.source.orientation);
    // here you react to the startup orientation
    if (e.source.orientation === Ti.UI.LANDSCAPE_LEFT || e.source.orientation === Ti.UI.LANDSCAPE_RIGHT){
    if (OS_ANDROID){
        // this is not strictly necesary for setting the ActionBar title, but it's
        // good to have it here for other ActionBar-related operations
        var actionBarHelper = require('actionbarhelper')(e.source)
// listen for orientation changes
Ti.Gesture.addEventListener('orientationchange', function(e) {
    console.log("Orientation changed to: " + e.orientation);
    // here you react to the change in orientation
    if (e.orientation === Ti.UI.LANDSCAPE_LEFT || e.orientation === Ti.UI.LANDSCAPE_RIGHT){
function updateUI(isPortrait){
    // here you update the UI based on the current orientation
    if (isPortrait){
        console.log('Adjusting for portrait');
        console.log('Adjusting for landscape');

We’ll add an event listener to the open event of the Window, and from there we can grab the orientation property. We also add an event listener to Ti.Gesture and listen for the orientationchange event. In any case, the action is the same: call the updateUI function.
There’s no real magic here. In this function we simply redistribute the percentages; we don’t do anything to the individual objects. That’s the beauty of using flexible boxes: by changing the dimensions of the parent we are proportionally changing the dimensions of all the children. In this example I’m simply setting the bottom box to 0% and distributing the rest as 50%/50%. The result is a slightly different rendering when running in landscape mode. This should give you ideas on how to make UI decisions and make the best use of your available screen real-estate. The results are shown below.

This is a practical yet trivial example of how to use Views and listen to orientation changes. Also notice that I’m using Views instead of buttons, but that’s for illustration purposes only. This technique can be used with other objects like Labels, Buttons and TextFields. Finally, keep in mind that Alloy provides additional features like isTablet() , isHandheld() and the formFactor property that can be used to have a more granular way of creating screen layouts.

Previous articleSyncplicity by Axway Attends the 2014 RSA Conference, San Francisco
Next articleHow Satya Nadella Might Resurrect Microsoft


  1. I think that using relative values, compared to absolute values simplifies the development a lot. Yet unfortunately there are some subtle Titanium details that limit the usability of this feature, and this is namely performance. Put too much views on one screen, each with it’s own relative measures and you instantly receive a slow to render screen (e.g. simulating a bar chart). I had to rewrite all my positioning to use absolute values, just to make the screens a bit faster. And still I am very hesitant when putting a view with relative coordinates. Especially on the old iPhones 3GS and 4, this is serious due to the slow CPU. (and I believe – the IOS impl). Just run the IOS Profiler on an app with lot’s of views, and you will be astonished – what’s done behind on each refresh of those views.
    So for sure this is a good thing – but it has to be use cautiously in such corner cases.

  2. https://developer.appcelerator.com/question/148337/how-to-achieve-same-layout-for-android-and-iphone-using-titanium
    From the above link it is clearly suggested to use “dp” instead of “percentage”. But here the above example is implemented using percentage. So it again lands me to question of whether to use dp or percentage as we need to develop apps for different platforms.
    There is orientaion issue when using “dp” which forces us to lock the orientation to either landscape or potrait mode. Any solution regarding this problem.

    • Hi Aniruddha,
      Dp refers to absolute positioning and percentages are relative positioning, so they are two different approaches. That is, if you use Dp, or pixels, or any other absolute unit of measurement, you’re telling your object exactly where you want it to be with respect to the screen’s total size and orientation, assuming you have that information, which is very challenging for Android devices. So if you know the size of the screen, then use absolute positioning to avoid the dynamic recalculation of coordinates.
      There will be a follow-up post expanding exceptions to the “percentages rule”.

  3. Hi Ricardo,
    I want to ask you, why you use this convention:
    instead of this:

  4. i am using % wise screen design for android working very fine for All mobile device but if am goint to user DP it make issues for background images ? what can be problem here ?

  5. Ricardo,
    Precisely the info I needed when I needed it. I easily adapted your example for horizontal “button bar” style views. I’ve been struggling with getting accurate relative spacing for the last couple of days.
    This blog solved that problem straight away.
    Michael Stelly
    Lead Mobile Developer
    Transamerica Retirement Solutions.

  6. A very difficult solution for a very simple problem.
    You shouldve just said ‘these buttons are each 40dp high’, add so in the *.tss files and you’re done. I try to avoid any solution that requires excessive styling in the controller because thats not ‘logic’ to me


Please enter your comment!
Please enter your name here