NativeScript Core

Bottom Navigation

Disclaimer: The BottomNavigation component is currently in Beta version. The component is being actively developed - use the tracking issue for details about the ongoing implementation.

The BottomNavigation component provides a simple way to navigate between different views while providing common UI for both iOS and Android platforms. The recommended scenario suitable for BottomNavigation is a high level navigation with 3 to 5 tabs each with separate function. For additional information and details about bottom navigation refer to the Material Design guidelines.

Note: NativeScript 6 introduced two new UI components called BottomNavigation and Tabs. The idea behind them is to provide more control when building tab based UI, while powering the CSS styling, the icon font support and other specific functionalities. Prior to NativeScript 6, we had the TabView component which had top and bottom implementations with different behavoirs for the different platofrms and some styling limitations. With BottomNavigaiton and Tabs coomponents available, the TabView can be considered obsolete.

The BottomNavigation component roundup

Component Primary Objectives:

  • Used for High Level navigation.
  • Good for UX structure with 3 to 5 different options.

Limitations

  • No navigation transitions.
  • No navigation gestures (e.g., swipe to navigate).
  • No content preloading.

Usage

The BottomNavigation component contains two sub-components:

  • The TabStrip which defines and rendres the bottom bar and its TabStripItem components.
  • Multiple TabContentItem components which total number should be equal to the number of the tabs (TabStripItem components). Each TabContentItem acts as a container for your tab content.
<BottomNavigation selectedIndex="1">

    <!-- The bottom tab UI is created via TabStrip (the containier) and TabStripItem (for each tab)-->
    <TabStrip>
        <TabStripItem title="Home" iconSource="res://baseline_home_black_18pt"></TabStripItem>
        <TabStripItem title="Account" iconSource="res://baseline_account_balance_black_18pt"></TabStripItem>
        <TabStripItem title="Search" iconSource="res://baseline_search_black_18pt"></TabStripItem>
    </TabStrip>

    <!-- The number of TabContentItem components should corespond to the number of TabStripItem components -->
    <TabContentItem>
        <GridLayout>
            <Label text="Home Page" class="h2 text-center"></Label>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <Label text="Account Page" class="h2 text-center"></Label>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <Label text="Search Page" class="h2 text-center"></Label>
        </GridLayout>
    </TabContentItem>

</BottomNavigation>

Note: The number of TabStripItem components must be equal to the number of tabContentItem components.

Improve this document

Demo Source


Theming

Note: - The integration with nativescript-theme and the support for custom CSS is currently under development and is on its way.

BottomNavigation.bottom-nav {
    background-color: orangered;
    color: gold;
}

TabStripItem.tabstripitem-active {
    background-color: teal;
}

TabStripItem.tabstripitem-active:active {
    background-color: yellowgreen;
} 

TabContentItem.first-tabcontent {
    color: olive;
}
TabContentItem.second-tabcontent {
    color: aquamarine;
}
TabContentItem.third-tabcontent {
    color: antiquewhite;
}

Improve this document

Demo Source


Properties

  • items: Array<TabContentItem>; - Gets or sets the items of the BottomNavigation.

  • tabStrip: TabStrip; - Gets or sets the tab strip of the BottomNavigation.

  • selectedIndex: number; - Gets or sets the selectedIndex of the BottomNavigation.

  • android: any /* android.view.View */; - Gets the native android widget that represents the user interface for this component. Valid only when running on Android OS.

  • ios: any /* UITabBarController */; - Gets the native iOS UITabBarController that represents the user interface for this component. Valid only when running on iOS.

const TabStrip = require("tns-core-modules/ui/bottom-navigation").TabStrip;
const TabStripItem = require("tns-core-modules/ui/bottom-navigation").TabStripItem;
const TabContentItem = require("tns-core-modules/ui/bottom-navigation").TabContentItem;

exports.onBottomNavLoaded = (args) => {
    // BottomNavigation
    const bottomNav = args.object;
    /*
        Using the items property to assign array of TabContentItem components (with content)
        Note: The number of TabContentItem components should be equal to the number of TabStripItem components
    */
    const tabContentItemsArray = createTabsContentArray();
    bottomNav.items = tabContentItemsArray;

    /*
        Using the tabStrip property to createa a TabStrip with multiple TabStripItems (tabs)
        Note: The number of TabStripItem components should be equal to the number of TabContentItem components
    */
    const tabStrip = createTabStrip();
    bottomNav.tabStrip = tabStrip;

    /*
        Using the selectedIndex property
    */
    bottomNav.selectedIndex = 1;

    /*
        Using the nativeView property (correspnding to bottomNav.ios or bottomNav.android depending on the used platform)
    */
    console.log("bottomNav.nativeView: ", bottomNav.nativeView);
};
import { EventData } from "tns-core-modules/data/observable";
import { BottomNavigation, TabStrip, TabStripItem, TabContentItem } from "tns-core-modules/ui/bottom-navigation";

export function onBottomNavLoaded(args: EventData) {
    const bottomNav = args.object as BottomNavigation;

    /*
        Using the items property to assign array of TabContentItem componentns
        Note: The number of TabContentItem components should be equal to the number of TabStripItem components
    */
    const tabContentItemsArray: Array<TabContentItem> = createTabsContentArray();
    bottomNav.items = tabContentItemsArray;

    /*
        Using the tabStrip property to createa a TabStrip with multiple TabStripItems (tabs)
        Note: The number of TabStripItem components should be equal to the number of TabContentItem components
    */
    const tabStrip = createTabStrip();
    bottomNav.tabStrip = tabStrip;

    /*
        Using the selectedIndex property
    */
    bottomNav.selectedIndex = 1;

    console.log(bottomNav.nativeView);
}

Improve this document

Demo Source


Events

  • selectedIndexChanged - Event used to track the tabs interaction though the change of selectedIndex property of BottomNavigation component. The event data is of type SelectedIndexChangedEventData extends EventData with two new properties:
    • oldIndex - Provides the old selected index.
    • newIndwex - Provides the new selected index.
exports.onBottomNavLoaded = (args) => {
    // Using the loaded event to ger a reference to the BottomNavigation
    const bottomNavigation = args.object;

    // Using selectedIndexChanged
    bottomNavigation.on("selectedIndexChanged", (args) => {
        // args is of type SelectedIndexChangedEventData
        const oldIndex = args.oldIndex;
        const newIndex = args.newIndex;
        console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);

        args.object.page.bindingContext.set("selectedIndex", newIndex);
    });
};
import { EventData, fromObject } from "tns-core-modules/data/observable";
import { BottomNavigation, SelectedIndexChangedEventData } from "tns-core-modules/ui/bottom-navigation";
export function onBottomNavLoaded(args: EventData) {
    // Using the loaded event to ger a reference to the BottomNavigation
    const bottomNavigation = args.object as BottomNavigation;

    // Using selectedIndexChanged
    bottomNavigation.on(BottomNavigation.selectedIndexChangedEvent, (data: SelectedIndexChangedEventData) => {
        const oldIndex: number = data.oldIndex;
        const newIndex: number = data.newIndex;
        console.log(`oldIndex: ${oldIndex}; newIndex: ${newIndex}`);

        (<any>args.object).page.bindingContext.set("selectedIndex", newIndex);
    });
}

Improve this document

Demo Source


Tips And Tricks

Icon Fonts in BottomNavigation

Using icon fonts to customize the UI of your TabStripItem components is possible through the font:// prefix for the iconSource property.

<BottomNavigation selectedIndex="1" class="fas font-size">
    <!-- Using icon fonts for each TabStripItem -->
    <TabStrip>
        <TabStripItem title="Home" iconSource="font://&#xf015;"></TabStripItem>
        <TabStripItem title="Account" iconSource="font://&#xf2bd;"></TabStripItem>
        <TabStripItem title="Search" iconSource="font://&#xf002;"></TabStripItem>
    </TabStrip>

    <TabContentItem>
        <GridLayout>
            <Label text="Home Page" class="h2 text-center"></Label>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <Label text="Account Page" class="h2 text-center"></Label>
        </GridLayout>
    </TabContentItem>
    <TabContentItem>
        <GridLayout>
            <Label text="Search Page" class="h2 text-center"></Label>
        </GridLayout>
    </TabContentItem>

</BottomNavigation>

Improve this document

Demo Source


API Reference for the BottomNavigation Class

Native Component

Android iOS
FrameLayout UITabViewController