Android Window Orientation behavior change for 1.7.2

Computer Science as a Abstract Background Art

With the release of Titanium Mobile SDK 1.7.2, we are making some changes to orientation behavior focused mainly on Android. These changes bring the behavior more in line with how orientation works in a native app and enhance our support for tablet and 3.x (Honeycomb) devices.

In order to understand the driving force behind the changes, it is important to understand the orientation behavior on Android.  There are a few key things to remember when dealing with orientation in Android:

1)  Orientation values that can be requested go beyond the values that get reported back when orientation actually changes.  For example:  when setting orientation in a native app, you may be able to ask for reverse portrait or reverse landscape but Android itself will only report whether the orientation is portrait or landscape – not the specific type of portrait or landscape.  On many devices you can make assumptions regarding the sensor degrees of the device and do a little math to determine the orientation but that brings us to the next point…

2)  Orientation values do not match up to sensor degrees across all devices.  For example:  on a Droid 2, portrait mode (the primary mode) is when the “top” of the device is at the 0 degree position and landscape mode (secondary mode) is when the “top” of the device is at the 270 degree position.   On a Xoom however, landscape mode (the primary mode) is when the “top” of the device is at the 0 degree position and portrait mode (secondary mode) is when the “top” of the device is at the 90 degree position.  Note the difference in the secondary modes.  Due to the hardware configuration of the device (location of the camera, etc) the position of a certain orientation mode may not be exactly where you expect it to be.

Given this understanding, its important to mentally break apart the values you use when setting orientation versus the value you get when requesting orientation.  The value you get when requesting the current orientation is geared more toward the general orientation of the device (useful for knowing what resources to use).  The values you use to set orientation are actually much more detailed allowing for setting the specific orientation of the device.

Our changes

Titanium.UI.orientation is now deprecated and should no longer be used for setting orientation mode.  Instead, it is suggested to set the orientation mode or modes on the Titanium.UI.Window.orientationModes property since orientation in Titanium is linked to the window itself.

The following lists the orientation behavior that can be expected when setting various modes on Titanium.UI.Window.orientationModes:

  1. Any portrait mode AND any landscape mode:  this combination will set the screen orientation to be driven by the sensor and default OS behavior.
     

     
  2. Both portrait modes:  on API level 9 (2.3.0) and above, this will set the screen orientation to be “sensor portrait” which allows the OS to shift the orientation to either of the portrait orientation modes based on what the sensor reports.  If the device is older than API level 9 then this will lock the orientation to what the device considers portrait.
     

     
  3. Both landscape modes:  same as #2, just for landscape.
     

     
  4. Portrait mode:  locks orientation to portrait
     

     
  5. Landscape mode: locks orientation to landscape
     

     
  6. None:  if you set the Titanium.UI.Window.orientationModes array to be empty, then this defaults back to full sensor mode (same as #1)
     

     

Additional Resources

Kitchen Sink examples:
https://github.com/appcelerator/titanium_mobile/blob/master/demos/KitchenSink/Resources/examples/orientation.js

1 COMMENT

  1. This (below) doesn’t seem to work…

    var win = Ti.UI.createWindow({
    fullscreen:false,
    navBarHidden:true
    orientationModes:[Ti.UI.PORTRAIT]
    });

    but if I add this line:

    win.orientationModes=[Ti.UI.PORTRAIT]

    it does work… Is there any reason why it can’t be declared when the initial window is declared? Or a reason that initial declaration is ignored?

    On a similar note, I’d love to see the tweetanium app fully configured to work in portrait mode on android including being limited to a portrait loading screen. I’ve had limited success in getting android to maintain a portrait orientation throughout an app despite my adding android:screenOrientation=”portrait” to every android activity in a custom AndroidManifest.xml file. I’ve had it work and then then stop working seemingly randomly.

  2. Hey!

    Would be awesome if one could lock an app to an orientation mode. You know, ‘always default to portrait’. If there was a setting like that… It would be really great…

  3. Sergej,

    You can lock the orientation mode on android, by having a custom android manifest.xml and declaring the orientation mode for each activity.

  4. I believe that Sergej’s point is that regardless of whether or not you can define it per activity, you should be able to define it for a whole app.

    Copying the activities from my generated AndroidManifest into my tiapp.xml and setting them all to portrait still leaves me with certain windows that are launched from tab windows (model windows?) that will orientate as they please, irritating.

  5. To clarify, I fixed it by applying:

    Ti.UI.currentWindow.orientationModes = [
    Titanium.UI.PORTRAIT,
    Titanium.UI.UPSIDE_PORTRAIT
    ];

    On the individual windows, I’m sure I could have instead worked out what activities the model windows represent, but I don’t know (or have the desire to find out) how the internals of Android work in this regard, you should just be able to set orientation globally, even if Android doesn’t support it natively (which is my understanding), it could be implemented easily in the abstraction and applied to all activities.