Have you seen all of the free code samples available on our Marketplace?

NativeScript Angular

Tab View

The TabView component provides a simple way to navigate between different views by tapping on some of the tabs or by swiping between the views. By default the TabView will load the view of the first tab, however it is possible to load alternative tabs when the app starts by setting the component’s selectedIndex property.

The general behaviour of the TabView component is to load its items demand. This means that every TabViewItem view will be loaded when it is shown and will be unloaded when it disappears. Respectively loaded and unloaded events will be fired while showing or hiding each view. However, there are some specifics for each platform(iOS and Android), which are described in the notes below.

Note (iOS specific): UITabBarController is used in the implementation, which means that only one TabViewItem can be shown at a given time and only one needs to be loaded. When the user selects a new TabViewItem, we load the new item and unload the previous one.

Note (Android specific): In the Android implementation is used ViewPager controller, which allows using the swipe gesture to navigate to the next or previous tab. This means that only one TabViewItem can be shown, but multiple TabViewItems need to be loaded. Otherwise, after left or right swipe, you will not see the TabViewItem's contents, after the swiping. By default, the ViewPager controller will pre-load one TabViewItem on the left and on on the right. Regarding that, if one of the items is already pre-loaded, it will not be loaded again. In the Android, we have exposed a property called androidOffscreenTabLimit, which allow specifying, how many components should be pre-load on the left and right (if you are setting up androidOffscreenTabLimit to 0, the Android TabView will match to the iOS TabView).

The iOS and Android UX guidelines regarding the Tab controls differ greatly. The difference is described in the below points:

  • The iOS tabs have their tab bar, which will be displayed always on the bottom and does not allow swipe gesture for changing tabs.
  • The Android tabs are on top and will enable the swipe navigation between the tabs.
  • For Android we have androidTabsPosition property which has two options top(default value) and bottom. Setting up this property to bottom allows mimicking Bottom Tab Navigation control(provided by android support library v25 release). Setting the Tabs at the bottom will disable the swipe navigation and the items preloading functionality.

Image

Basic Tab View

Using a TabView inside an Angular app requires some special attention about how to provide title, iconSource and content (view) of the TabItem. In a pure NativeScript application, TabView has an items property which could be set via XML to an array of TabViewItems (basically, an array of objects with title and view properties). However, NativeScript-Angular does not support nested properties in its HTML template, so adding TabViewItem to TabView is a little bit different. NativeScript-Angular provides a custom Angular directive that simplifies the way native TabView should be used. The following example shows how to add a TabView to your page (with some clarifications later):

HTML

<TabView selectedIndex="0"  (selectedIndexChange)="onIndexChanged($event)" sdkExampleTitle sdkToggleNavButton>
    <StackLayout *tabItem="{title: 'NativeScript'}">
        <Label text="NativeScript" class="m-15 h2 text-left" color="blue"></Label>
        <ScrollView>
            <Label [text]="content" textWrap="true" class="m-15"></Label>
        </ScrollView>
    </StackLayout>
    <StackLayout *tabItem="{title: 'Icon'}">
        <Image class="m-t-30 m-b-15" src="res://icon" width="80" height="80"></Image>
        <Label text="NativeScript" textWrap="true" class="h2 m-x-auto" color="blue"></Label>
    </StackLayout>
</TabView>
  • tabItem: The TabView directive uses a JSON object to transfer properties to the native object. Actually, TabViewItem is a pretty simple object with just title, iconSource and view properties. Since title and iconSource are usually represented as text, TabView directive uses a small JSON object ({title: 'Profile', iconSource: '~/icon.png'}) to define these properties easily in HTML. View, however, is not so simple, therefore as TabViewItem. View TabView directive uses the tag where tabItem attribute is set.

This is a typical usage of the TabView directive; however, if further customization is required, there are a few options available.

Improve this document

Demo Source


Binding Tab View Items

You can use the NativeScript-Angular TabView selectedIndex property in two-way binding scenarios. Using this kind of binding is relatively simple. Just use the standard ngModel syntax to a data model property (for the sake of example, the TabViewTest class is used as binding context) and set the data model property tabSelectedIndex to the desired value.

HTML

<TabView [(ngModel)]="tabSelectedIndex" selectedColor="#FF0000" iosIconRenderingMode="alwaysOriginal" sdkExampleTitle sdkToggleNavButton>
    <StackLayout *tabItem="{title: 'Profile', iconSource: 'res://icon'}">
        <StackLayout>
            <Label [text]="'Profile Tab (tabSelectedIndex = '+ tabSelectedIndex +')'" class="h2 m-t-16 text-center" textWrap="true"></Label>
            <Button text="Change Tab via ngModel" (tap)="changeTab()" class="btn btn-primary btn-active"></Button>
        </StackLayout>
    </StackLayout>
    <StackLayout *tabItem="{title: 'Stats'}">
        <StackLayout>
            <Label [text]="'Stats Tab (tabSelectedIndex = '+ tabSelectedIndex +')'" class="h2 m-t-16 text-center" textWrap="true"></Label>
            <Button text="Change Tab via ngModel" (tap)="changeTab()" class="btn btn-primary btn-active"></Button>
        </StackLayout>
    </StackLayout>
    <StackLayout *tabItem="{title: 'Settings'}">
        <StackLayout>
            <Label [text]="'Settings Tab (tabSelectedIndex = '+ tabSelectedIndex +')'" class="h2 m-t-16 text-center" textWrap="true"></Label>
            <Button text="Change Tab via ngModel" (tap)="changeTab()" class="btn btn-primary btn-active"></Button>
        </StackLayout>
    </StackLayout>
</TabView>

TypeScript

public tabSelectedIndex: number;

constructor() {
    this.tabSelectedIndex = 1;
}

changeTab() {
    if (this.tabSelectedIndex === 0) {
        this.tabSelectedIndex = 1;
    } else if (this.tabSelectedIndex === 1) {
        this.tabSelectedIndex = 2;
    } else if (this.tabSelectedIndex === 2) {
        this.tabSelectedIndex = 0;
    }
}

Improve this document

Demo Source


Customizing Tab View Items

The most common customization of TabView is customizing the background color of the selected tab item to use something other than the first tab item for start up. The following example shows how to achieve that with a few modifications to the previous example.

HTML

<TabView selectedIndex="1" selectedColor="#FF0000" iosIconRenderingMode="alwaysOriginal" sdkExampleTitle sdkToggleNavButton>
    <StackLayout *tabItem="{title: 'Profile', iconSource: 'res://icon'}" >
        <Label text="First tab item"></Label>
    </StackLayout>
    <StackLayout *tabItem="{title: 'Stats'}">
        <Label text="Second tab item"></Label>
    </StackLayout>
    <StackLayout *tabItem="{title: 'Settings'}">
        <Label text="Third tab item"></Label>
    </StackLayout>
</TabView>

The result is a TabView that selects the second tab at start up and uses the color red for the selected tab.

Improve this document

Demo Source


Tab View Icon Fonts

HTML

<TabView class="icon" selectedIndex="0" sdkExampleTitle sdkToggleNavButton>
    <StackLayout *tabItem="{title: '&#xe913;'}">
        <Label text="First TabView item with Icon Font" textAlignment="center" textWrap="true" class="h2 m-x-auto" color="blue"></Label>
        <Label text="&#xe913;" textWrap="true" class="h2 m-x-auto" color="blue"></Label>
    </StackLayout>
    <StackLayout *tabItem="{title: '&#xe908;'}">
        <Label text="Second TabView item with Icon Font" textAlignment="center" textWrap="true" class="h2 m-x-auto" color="green"></Label>
        <Label text="&#xe908;" textWrap="true" class="h2 m-x-auto" color="green"></Label>
    </StackLayout>
</TabView>

Improve this document

Demo Source


Tab View Items

HTML

<TabView selectedIndex="0" (selectedIndexChange)="onIndexChanged($event)" sdkExampleTitle sdkToggleNavButton>
    <StackLayout *tabItem="{title: 'NativeScript',  iconSource: 'res://logo_white_bg'}">
        <Label text="TabView item with Icon" textWrap="true" class="h2 m-x-auto" color="blue"></Label>
    </StackLayout>
    <StackLayout *tabItem="titleAndIcon">
        <Label text="TabView item with observable title and icon" textWrap="true" class="h2 m-x-auto" color="blue"></Label>
    </StackLayout>
</TabView>

TypeScript

import { Component } from "@angular/core";
import { StackLayout } from "ui/layouts/stack-layout";

import { TabView, SelectedIndexChangedEventData, TabViewItem } from "ui/tab-view";

@Component({
    moduleId: module.id,
    templateUrl: "./tab-view-items.component.html",
})
export class TabViewItemsComponent {
    public titleAndIcon: any = { title: "Icon", iconSource: "res://icon" };

    public onIndexChanged(args) {
        let tabView = <TabView>args.object;
        console.log("Selected index changed! New inxed: " + tabView.selectedIndex);
    }
}

Improve this document

Demo Source


Tabs Limit

Setting up the limit of the tabs, which should be pre-loaded on the left and right sides.

<GridLayout sdkExampleTitle sdkToggleNavButton>
    <TabView selectedIndex="0" androidOffscreenTabLimit="0"  >
        <StackLayout *tabItem="{title: 'First Tab'}">
            <Label text="First Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
        <StackLayout *tabItem="{title: 'Second Tab'}">
            <Label text="Second Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
        <StackLayout *tabItem="{title: 'Third Tab'}">
            <Label text="Third Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
        <StackLayout *tabItem="{title: 'Fourth Tab'}">
            <Label text="Fourth Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
    </TabView>
</GridLayout>

Improve this document

Demo Source


Tabs Position

Setting up the bottom Tabs position for Android.

<GridLayout sdkExampleTitle sdkToggleNavButton>
    <TabView selectedIndex="0" androidTabsPosition="bottom"  >
        <StackLayout *tabItem="{title: 'First Tab'}">
            <Label text="First Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
        <StackLayout *tabItem="{title: 'Second Tab'}">
            <Label text="Second Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
        <StackLayout *tabItem="{title: 'Third Tab'}">
            <Label text="Third Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
        <StackLayout *tabItem="{title: 'Fourth Tab'}">
            <Label text="Fourth Tab" class="m-15 h2 text-left" color="blue"></Label>
            <ScrollView>
                <Label [text]="content" textWrap="true" class="m-15"></Label>
            </ScrollView>
        </StackLayout>
    </TabView>
</GridLayout>

Improve this document

Demo Source


API Reference for the TabView Class

Native Component

Android iOS
android.support.v4.view.ViewPager UITabBarController