# Android Action Bar

The action bar is a major UI feature for Android applications in Android 3.0 and later. To understand all of the features of the action bar and its place in Android applications, we recommend reviewing the Android Design: Action Bar (opens new window) and the Action Bar API guide (opens new window) on the Android developer site.

# Hiding the action bar

Titanium shows an Action Bar by default in all windows. If you do not want to show them, then there are 2 ways to do so.

In a theme XML file, you can remove the Action Bar from the window when it is opened.

As of Titanium 10.0.0, it's recommended to use one of the below themes to remove the Action Bar. These themes derive from the AndroidManifest.xml file's <application/> assigned theme, which is set to a material theme by default. The "NoTitleBar" theme removes the Action Bar. The "Fullscreen" theme removes both the Action Bar and Status Bar.

  • "Theme.AppDerived.NoTitleBar"

  • "Theme.AppDerived.Fullscreen"

For Titanium 9.3.x, it's recommended to use the following themes to remove the Action Bar. These themes derive from the AndroidManifest.xml file's <application/> assigned theme, like the above. These themes are deprecated as of Titanium 10.0.0.

  • "Theme.Titanium.NoTitleBar"

  • "Theme.Titanium.Fullscreen"

For Titanium versions older than 9.3.0, you can use the below themes to remove the Action Bar. Note that these derive from Google's "Theme.AppCompat" theme. If your define your own custom theme in <application/>, then you should create your own equivalent of the below themes yourself.

  • "Theme.AppCompat.NoTitleBar"

  • "Theme.AppCompat.Fullscreen"

You can then remove the Action Bar from all windows by default by setting the theme in the tiapp.xml file's <application/> element.

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
        <application android:theme="@style/Theme.AppDerived.NoTitleBar"/>
    </manifest>
</android>

In JavaScript code, you can hide/remove the Action Bar 2 different ways. This is preferred if you only want to hide an Action Bar in particular windows, not all windows.

You can remove the Action Bar before by setting the window's "theme" creation property.

// Set a theme which does not have an Action Bar.
const win = Ti.UI.createWindow({
 theme: 'Theme.AppDerived.NoTitleBar'
});
win.open();

Alternatively, you can hide the Action Bar after the window is opened by getting the activity's action bar instance and call the hide method.

// Hide the Action Bar after the window has been opened.
const win = Ti.UI.createWindow();
win.addEventListener("open", () => {
    if (OS_ANDROID) {
        win.activity.actionBar.hide();
    }
});
win.open();

# Action bar tabs

For Titanium 8.0.0 and higher, tabs are never shown within the action bar.

For Titanium 7.x.x and older versions, a tab group might display its tabs within the action bar depending on device orientation and the size of the screen. The actual display of the tabs depends on the number of tabs and the amount of screen space available. If there is not enough space to fit all of the tabs on the action bar, Android may display scrolling tabs or a drop-down list instead.

Action items For action items, you can add items to the action bar by creating menu items and specifying the new showAsAction property. Valid values are:

  • SHOW_AS_ACTION_ALWAYS. Show item in action bar.

  • SHOW_AS_ACTION_IF_ROOM. Show item in action bar if space permits, or in the overflow menu otherwise.

  • SHOW_AS_ACTION_NEVER. Only show item in the overflow menu. This is the default.

You can OR the above values with one of the following modifiers:

  • SHOW_AS_ACTION_WITH_TEXT. Show the action item text instead of its icon, if space permits.

  • SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW. Create a standard action item button that can be "expanded" to show an action view.

The following code sample creates a basic action item:

win1.activity.onCreateOptionsMenu = function(e) {
  var menu = e.menu;
  var menuItem = menu.add({
    title: "Compose",
    icon: "images/compose_icon.png",
    showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM
  });
  menuItem.addEventListener("click", function(e) {
    Ti.API.info("Action Item Clicked!");
  });
};

Android has very specific guidelines for action item icons, including density-specific size requirements. So you'll probably want to generate icons for each density and store them in the density-specific folders in Resources/android. For example, Resources/android/images/res-hdpi.

To specify a view to use in place of the the default action item button, use the actionView property. When you add an action view to an action bar, the native view underlying the Titanium view is inserted into the action bar. The view will only be visible if the underlying native view has an inherent size. For example, a Button or ImageView corresponds to an Android native control that is sized based on its contents, so will appear in the action bar. Any Titanium layout properties specified on the view (such as width and height) are ignored by the native Android layout system.

If showAsAction is set to SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW is specified, the icon or title is shown when the item is collapsed, and the action view is shown when the item is expanded. When expanded, the action view takes over most of the action bar, and other action items are hidden. The MenuItem object supports two new methods, expandActionViewand collapseActionView, and accompanying expand and collapse events. The most common use of the expandable action item is for Android search widget, Ti.UI.Android.SearchView.

When creating action items, keep in mind:

  • The behavior of SHOW_AS_ACTION_WITH_TEXT is rather unpredictable; if you specify an icon and SHOW_AS_ACTION_WITH_TEXT, the Android OS still may choose to display either the text or the icon, depending on how much space is available in the action bar. This determination may vary based on which orientation an application was launched in, so the setting should be used with care if your application supports multiple orientations. To force Android to display text for an action item, specify a title but no icon. Note that Android displays either text or an icon in the action bar. If you need to include both text and an icon, you can create a Titanium button with both text and icon, and add it as the actionView.

  • When an action item is displayed in the overflow menu (for example, when specified with SHOW_AS_ACTION_IF_ROOM or SHOW_AS_ACTION_NEVER), it is displayed as text, without an icon. This is the way the overflow menu is meant to behave. It may cause some confusion because it differs from the way items are displayed in the action bar (where they use the icon if available) and in the legacy Android menu (where both icon and text are displayed).

  • You should always specify a title for an action item. Titles are used to display in the overflow menu, and are also displayed as hints when the user long-presses on an action item.

  • Only a few items can be displayed in the action bar. See the Android Design: Action Bar (opens new window) for guidelines on selecting action items.

# Dynamically updating action items

Since the options menu is considered always open when the action bar is in use, onCreateOptionsMenu is only called when the window or tab group is opened. To force the onCreateOptionsMenu method to be executed again, call Activity.invalidateOptionsMenu. The following code sample shows one way to switch the action items when the user changes tabs in a tab group.

// Copy and paste this code to the end of the Classic Default Project
if (Ti.Platform.name === "android") {
    tabGroup.addEventListener("open", function(e) {
        var activity = tabGroup.getActivity();
        activity.onCreateOptionsMenu = function(e) {
            var item, menu;
            menu = e.menu;
            menu.clear();
            if (tabGroup.activeTab == tab1) {
                item = menu.add({
                    title: "Tab1 Item",
                    icon: "images/icon1.png",
                    showAsAction: Ti.Android.SHOW_AS_ACTION_ALWAYS
                });
            } else if (tabGroup.activeTab == tab2) {
                item = menu.add({
                    title: "Tab2 Item",
                    icon: "images/icon2.png",
                    showAsAction: Ti.Android.SHOW_AS_ACTION_IF_ROOM
                });
            }
        };
    });

    tabGroup.addEventListener("focus", function(e) {
        tabGroup.getActivity().invalidateOptionsMenu();
    });
}

# Other action bar features

Direct access to some action bar methods and properties is available through the Activity.actionBar property. The activity and action bar objects are not created until the associated window or tab group is opened. Initial updates to these objects should be done in the open event handler for the window or tab group.

Currently, the tab group activity is only available from using the TabGroup.getActivity method.

To receive a callback when the home icon is clicked, set the ActionBar.onHomeIconItemSelected property to a callback function:

win.addEventListener("open", function(evt) {
  var actionBar = win.activity.actionBar;
  actionBar.onHomeIconItemSelected = function() {
    Ti.API.info("Home clicked!");
  };
});

You can use the ActionBar title, backgroundImage, icon, and logo properties to set the title, background, app icon, and app logo used in the action bar, respectively. Set the ActionBar.displayHomeAsUp property to true to display the "up" affordance. ActionBar also provides show and hide methods to show and hide the action bar. For example, to show the "up" affordance on a tab group's action bar you could use code like this:

var activity = tabGroup.getActivity();
if (activity != undefined && activity.actionBar != undefined) {
  activity.actionBar.displayHomeAsUp = true;
}

# Theming the action bar

As of Titanium 10.0.0, you can change the colors of the action bar via the material "actionBarTheme" style, which overrides the colors set by "actionBarStyle" in the theme. You would do this by creating an XML file in the platform/android/res/values folder as shown below.

platform/android/res/values/values.xml

<style name="MyTheme" parent="@style/Widget.AppCompat.ActionBar">
    <!-- My custom action bar theme with a white background and black text. -->
    <style name="ThemeOverlay.MyActionBar.Light" parent="@style/ThemeOverlay.MaterialComponents.Light">
        <item name="colorPrimary">#FFFFFF</item>
        <item name="colorSurface">#FFFFFF</item>
        <item name="colorOnSurface">#000000</item>
        <item name="android:textColorPrimary">#000000</item>
        <item name="android:textColorSecondary">#000000</item>
    </style>

    <!-- My custom app theme using above white action bar theme. -->
    <!-- Note: This is only supported on Titanium 10.0.0 or higher. -->
    <style name="Theme.MyTheme" parent="@style/Theme.Titanium.Light">
        <item name="actionBarTheme">@style/ThemeOverlay.MyActionBar.Light</item>
    </style>
</style>

You would then set the above theme to your application in the tiapp.xml as follows.

tiapp.xml

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
        <application android:theme="@style/Theme.MyTheme"/>
    </manifest>
</android>

# Styling the action bar

For Titanium 9.x.x and older, your only option to change the colors of the action bar is via "actionBarStyle" in a custom theme. You can customize the "actionBarStyle" in Titanium 10.0.0, but the "actionBarTheme" (documented above) will override the style's colors. Note that "actionBarStyle" can be used to customize other aspects of the widget such as it text appearance, size, etc.

You would do this by creating an XML file in the platform/android/res/values folder as shown below.

platform/android/res/values/values.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Define a text color for the Action Bar title. -->
    <style name="TextAppearance.MyActionBarTitle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
        <item name="android:textColor">#000080</item>
    </style>

    <!-- My custom action bar style. -->
    <style name="Widget.MyActionBar" parent="@style/Widget.AppCompat.ActionBar">
        <item name="android:titleTextStyle">@style/TextAppearance.MyActionBarTitle</item>
        <item name="titleTextStyle">@style/TextAppearance.MyActionBarTitle</item>
        <item name="android:background">#ffa500</item>
    </style>

    <!-- My custom app theme using above white action bar theme. -->
    <!-- Note: This applies to Titanium 9.x.x and older versions. -->
    <style name="Theme.MyTheme" parent="@style/Theme.AppCompat">
        <item name="actionBarStyle">@style/Widget.MyActionBar</item>
    </style>
</resources>

You would then set the above theme to your application in the tiapp.xml as follows.

tiapp.xml

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
        <application android:theme="@style/Theme.MyTheme"/>
    </manifest>
</android>

# Further reading

# Testing in the emulator

To test on an emulator, you may need to configure some options to display the action bar and overflow menu. Note that the overflow option does not appear on emulators and devices running Android 2.3.x and earlier.

# Android emulator

When testing the action bar in the Android emulator, note that the action overflow menu is not displayed in the default emulator, because the default emulator represents a device with hardware buttons.

To configure the Android emulator to show the overflow menu:

  1. Make a note of the name of the emulator you're testing with (for example, titanium_25_WVGA800).

  2. Close the emulator.

  3. Run the Android AVD manager:

    android avd

    The android command is in the tools folder of the Android SDK folder.

  4. Select the emulator you're testing with and click Edit.

  5. Click New next to the Hardware list.

  6. Choose Hardware Back/Home Keys and click OK.

  7. Change the Hardware Back/Home Keys value to No. edit_avd_properties

  8. Click outside the Hardware list to confirm the value change; make sure the value for Hardware Back/Home Keys is still displayed as No.

  9. Click Edit AVD.

  10. Run your test application again.

# Genymotion emulator

If you do not see the overflow menu when testing on a Genymotion emulator, you may need to enable the navigation bar.

To enable the navigation bar, the emulator must not be currently opened, then:

  1. Start the Genymotion app.

  2. Select the emulator you want to configure, then click Configure button configure .

  3. Enable Show Android navigation bar, then click OK.

  4. Run your test application again.

GenymotinConfiguration

See also: