by

Dynamic menu for tab groups

NOTE: There’s a better way to do this described here.


Quoting the Titanium API docs: Prior to Titanium 3.0, menu items could be added to the individual windows of a tab group. Starting in Titanium 3.0, menus must be added to tab groups using the tab group’s activity. These changes were required to support the Android 3.0 action bar.

This is unfortunate, but I’ll show you how to work around this.

Why?

Because I like how the action bar can be used to display actions for the content of the current showing tab, or even show the title of the active tab, which would then be title-less themselves, like Twitter has:

Twitter action bar

How?

In a way that doesn’t require the controller of the tab group to know anything about its windows. Because, well.. that would be just bad programming. Instead, we use a custom event on the tab group’s tabs to simply pass on the task of setting the Android menu or action bar.

The tab group

Let’s take the following tab group. The example is in Alloy, but the controller code would translate to a classic project fairly easy.

index.xml

index.js

The controller of the tab group pretty much looks like the examples for Ti.Android.Menu. Like it says in the docs we need to wait till the tab group has opened and invalidate the menu to force it to be rebuild. We do the same on the focus event, which is fired when the active tab changes. Now the trick is to replace the actual logic for manipulating the Android menu or action bar with a custom event fired on the active tab. We pass everything the tab needs via the event dictionary.

The tabs

For both tabs and windows in the example we require the same controller-view.

tab.xml

tab.js
The controller takes the nr attribute of the Require element in the example index.xml above to help us identify the tabs and windows. The key now is to listen to the custom event we fire on the tab and pretty manipulate the menu or action bar as always. Both events have the e.menu property, but the onCreateOptionsMenu event also has e.activity and e.actionbar so we can manipulate those as well.

Requiring just the window

If other cases you would like to require just the windows and keep the tabs in the index.xml. In that case, just change $.index.activeTab to $.index.activeTab.window and in the window controller listen to the window for the custom event.

Action bar

To enable the action bar, make sure you target for API level 11 (Android 3.x) or above: