Appcelerator Blog

The Leading Resource for All Things Mobile

Android Tabs and ActionBar Menu Items

5 Flares 5 Flares ×

As you saw in my previous post about the Android AppCompat library, Titanium now shows the ActionBar by default. If you have never used the ActionBar, here’s a quick guide and sample project that covers the basics.

An important use-case that is not covered in that tutorial is the case where you have a TabGroup and want to have different actions items for each Tab, or even leave some Tabs without action items. When you have a TabGroup, the ActionBar belongs to the TabGroup, which is the main Activity, and not to each individual Window.

ab_tabs_menu

Menu items must be added to an Activity, so you can’t really add menu items to the individual Windows in the traditional way because Windows in a TabGroup are not Activities themselves, but rather children of the main Activity.

In order to have different action items for each tab you need to use the Activity’s onCreateOptionsMenu callback. This function is called when the Activity is created and is used to setup all the menu options. However, this happens only once when you launch your app, so options you set at this point will be global for the app.

The trick to make it work for different tabs is to be able to call it again every time you change tabs. To do this, the activity provides a method called invalidateOptionsMenu that removes all menu options and calls onCreateOptionsMenu again. Now let’s get to the code to see how to implement this.

Let’s say you have your TabGroup XML, defining two tabs, and the Windows included using the Require tag.


    
        
            
        
        
            
        
    

Inside your controller, create two convenience variables to store a pointer to the TabGroup and the id of the currently selected tab.

Alloy.Globals.tabGroup=$.index;
Alloy.Globals.currentTab=0;

Then, the magic happens in the “doopen” function. Inside this function we first obtain the Activity, and then we define the onCreateOptionsMenu callback:

var activity = evt.source.getActivity();
activity.onCreateOptionsMenu = function(e) {

}

Inside this callback we need to do two things: clear the current menu and set the actions required for the currently selected tab. To clear the menu is simple because it comes with the event object:

menu = e.menu;
menu.clear();

Then, do a switch on the currently selected tab:

switch(Alloy.Globals.currentTab){
        case 0: // menu options for tab 0
            item = e.menu.add({
                title : "Invite",
                showAsAction : Ti.Android.SHOW_AS_ACTION_ALWAYS,
                icon : Ti.Android.R.drawable.ic_menu_search
            });

            item.addEventListener("click", function(e) {
                $.win1.label.text='You clicked the magnifying glass';
            });

            break;
        case 1: // menu options for tab 1
            item = e.menu.add({
                title : "Share",
                showAsAction : Ti.Android.SHOW_AS_ACTION_ALWAYS,
                icon : Ti.Android.R.drawable.ic_menu_send
            });
            item.addEventListener("click", function(e) 
                $.win2.label.text='You clicked the send button';
            });
            break;
}

Now, the last thing we need to do is set the currentTab variable, and we do this via the TabGroup’s focus event. In this event we grab the value of the current tab, set it in our global variable, and then call invalidateOptionsMenu, which will remove all menu options and in turn, call onCreateOptionsMenu. This time around the tab id is different so execution will fall through a different condition in the switch.

Alloy.Globals.tabGroup.addEventListener("focus", function(evt) {
    if (typeof evt.index !== "undefined"){
        activity.invalidateOptionsMenu();
        Alloy.Globals.currentTab=evt.index; 
    } 
});

As opposed to iOS where a toolbar is a component of the Window, on Android the operating system manages the ActionBar (toolbar) and the menu options. It’s a different paradigm because on Android you’ll setup all your options in a single function regardless of the context in which they’ll be running, so understanding how this work is crucial for the architecture of your app.

I’m including a sample project so you can try it out by yourself.

5 Flares Twitter 0 Facebook 0 Google+ 3 LinkedIn 2 Email -- 5 Flares ×

4 Comments

  1. Thanks for the sample project. I can now experiment on this.

  2. What I use to do is let the onCreateOptionsMenu fire a “createOptionsMenu” event on the active tab’s window so the (required controller exporting the) window can hold the logic to populate the menu.

    • We also fire a onCreateOptionsMenu event which we can handle in the controllers, mainly because our entire app is build from widgets as we develop custom app for our customers put together from the same widgets. This way we can define the menu items in each widget and not rely on the creation of menu items in one single app dependent file.

  3. We can easily style Action Bar using Android’s style and theme resources. Android includes a few built-in activity themes that include “dark” or “light” action bar styles. You can also extend these themes to further customize the look for your action bar.

    Android includes two baseline activity themes that dictate the color for the action bar:

    1. Theme.Holo for a “dark” theme.

    2. Theme.Holo.Light for a “light” theme.

    For complete solution visit here:
    http://www.mindstick.com/Articles/b3e09326-1fd0-4ff6-9b86-7f3c5561b11e/Styling%20the%20Action%20Bar%20in%20Andriod

Comments are closed.

Sign up for updates!

Become a mobile leader. Take the first step to scale mobile innovation throughout your enterprise.
Get in touch
computer and tablet showing Appcelerator software
Start free, grow from there.
5 Flares Twitter 0 Facebook 0 Google+ 3 LinkedIn 2 Email -- 5 Flares ×