In building my first commercial app with Titanium Mobile, I ran into what I felt were some gaps in the API which I sought to fill with some library code. These classes and functions became so central to what I was doing that I felt they could be reusable in nearly any Titanium Mobile app. I named the library TitanUp, and I am making it available here to anybody who wants to use it, borrow from it, or extend it.
First off, let’s discuss the structure of the library. The code is all CommonJS-based, but it builds its own namespace (“TU”, for “TitanUp”). Anywhere in your code that you want to use any part of the library, you just do this:
var TU = require ("/TitanUp/TitanUp");
Some purists would argue against this approach from a performance standpoint. I contend that the functions in those 7 JS files are useful enough that you’re going to use them all anyway. Given that the performance hit isn’t too huge, it’s OK that you absorb that hit right at the launch of your app. Of course, your mileage may vary — if your app is loading 25 other JS files at startup, you may not be able to tolerate all 7 files loading at once. In that case, you may opt to use individual parts of the library rather than the whole thing.
Note that there are a lot of inter-dependencies in the library modules. For example, some of the Views may use the TU.UI.Theme module or the TU.UI.Sizer module. For that reason, you may have to use care if you want to use one of the modules without the whole library.
What does it do?
Enough about the structure of the library. What are some of the capabilities of TitanUp?
The device module rolls up a lot of the stuff in
Ti.Platform.displayCaps. Here are some of the more interesting capabilities.
Personally, I don’t like the way the Ti Mobile API provides
Ti.Platform.osname. I think they’re too similar and poorly named to be as useful as they could be. So I created my own property that sensibly (IMHO) returns ‘ios’ on all iOS devices, and ‘android’ on all ‘android’ devices.
Using the DPI of the screen and the display width and height, we can compute the physical size of the screen.
We can use information about the device (like
Ti.Platform.osname and the physical screen size) to determine whether we’re running on a tablet.
When you’re runnning an app in a TabGroup, you may want to know the working area of the window, sans title bars and tabs. This doesn’t compute it for you, but it provides a place for you to store that information upon the first
postlayout event fired by one of your windows.
The LocationManager class follows best practices for android and iOS location services while managing battery life by only querying for updates every 60 seconds.
I have found that in many cases, it is possible for a view to process a second event before the first event is done processing.
Imagine you have a button that is to open a new window. In most programming environments, you would expect that once the user clicks the button, the button would not process any more events until it is done with the event listener. And once it was done with the event listener, the new window would be covering up the button anyway, so there’d be no way to get two click events in a row.
But that’s not the way Titanium works; if you have a button that opens a new window, if the user taps very quickly, he may get two windows opened. You need to throttle the events so that the second one won’t be processed. TU.UI.EventThrottle provides a mechanism for doing such throttling. It can throttle events occurring within a certain time frame, or it can filter out events until a designated window closes.
Provides some help in constructing dynamically-sized user interface elements that look consistent across different screen densities. All while using the native units for android (pixels) and iOS (dips), which means that you don’t have to add qualifiers to your dimensions; you can just use numeric values.
Provides a simple, standardized way to manage colors and fonts in your application in a centralized location.
TU.UI.TGWM (TabGroup Window Manager)
Helps you to manage the opening/closing of windows within a TabGroup-based application so that your app can run happily on either iOS or android. Also adds the ‘tabactive’ and ‘tabinactive’ events to windows that are attached to tabs.
A mechanism to help you cope with the constraint of having a single MapView per application on android. Allows you to add/remove the single view from different windows without a lot of extra bookkeeping code.
An android/iOS picker that fits compactly into forms, while still using native controls.
An android/iOS selectbar that uses native controls (TabbedBar on iOS, a set of mutually-exclusive Switch controls on android).
Getting the code
Download the code from Github at https://github.com/jpriebe/TitanUp.
On November 17, I moved the code from google code to github. I think the github UI is a little easier to navigate, and certainly easier to download a tarball of the codebase.
The code I posted there has a few changes from my original release:
- TitanUp.Device now handles orientation changes
- TitanUp.UI.Views.SimplePicker now uses a window with a TableView for the popup on iOS, instead of the native picker that I was using — the picker didn’t fit onscreen in a tabbed UI in landscape mode
- added TitanUp.getVersion()