Nativescript: TabView icons

Created on 30 Mar 2017  路  11Comments  路  Source: NativeScript/NativeScript

I'm trying to have an alternating icon for the tabview. I'm trying to have a filled icon when the tab is selected. I saw documentation for xml with js. But was not able to find any for html with angular.

`

<StackLayout *tabItem="{title: 'Home', iconSource: 'res://home-outline.png\'}">
</StackLayout>

<StackLayout *tabItem="{title: 'Notification', iconSource: 'res://notification-outline.png'}">
</StackLayout>

<StackLayout *tabItem="{title: 'Profile', iconSource: 'res://profile-outline.png'}">
</StackLayout>

\
`

question

Most helpful comment

Hi guys,
I found a solution for me.

I use two different icons for the selection state and for the inactive state.
Also property iosIconRenderingMode value should be "alwaysOriginal".

In template:

<TabView tabBackgroundColor="#6E7AFA" androidTabsPosition="bottom" iosIconRenderingMode="alwaysOriginal" (selectedIndexChanged)="tabViewIndexChange($event)">
    <page-router-outlet *tabItem="homeTab" name="homeTab"></page-router-outlet>
    <page-router-outlet *tabItem="settingsTab" name="settingsTab"></page-router-outlet>
</TabView>

In component:

homeTab: any;
settingsTab: any;

constructor() {
    this.homeTab  = { iconSource: this.getIconSource("home") };
    this.settingsTab  = { iconSource: this.getIconSource("settings") };
}

tabViewIndexChange(args) {
    const index = args.newIndex;
    this.homeTab = { iconSource: this.getIconSource(index === 0 ? "home_selected" : "home") };
    this.settingsTab = { iconSource: this.getIconSource(index === 1 ? "settings_selected" : "settings") };
}

getIconSource(icon: string): string {
    const iconPrefix = isAndroid ? "res://" : "res://tabIcons/";
    return iconPrefix + icon;
}

All 11 comments

Hi @praven07 ,
Here you will find the part of the documentation, which shows, how to use TabView component in NativeScript Angular 2 project. To be shown properly the image on iOS you should also set up iosIconRenderingMode property to the component. For Example.

<TabView iosIconRenderingMode="alwaysOriginal">...</TabView>

Regarding that topic, you could also set up selectedTabTextColor property, however, this will change the color only of the text.

How do I alternate between an outline icon and a filled icon

For example like this.
home-outline 3x
home 3x

I want the outline icon to show when that tab is not selected and the filled icon to show when the tab is selected.

Hi @praven07,
In my further research, I found that you could set iosIconRenderingMode to alwaysTemplate, which will help you also to change the image color when some of the tabs have been selected.
For example:

<ActionBar title="My App" class="action-bar">
</ActionBar>
    <GridLayout >
        <TabView iosIconRenderingMode="alwaysTemplate" selectedTabTextColor="green">
            <StackLayout *tabItem="{title: 'Profile', iconSource:  '~/images/img1.png'}" >
                <Label text="First tap" textWrap="true"></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>
    </GridLayout>

In this case the selectedTabTextColor will be applied to the both title and iconSource.

Could you verify, whether this is applicable for you?

Hi! Yes I have that down. But I'm trying to achieve this functionality where you can see that the 'res://stack1' and 'res://stack' image toggles when the tab is selected or not. I want to use two different set of images where they alternate like shown in the code below.

I got this line of code from the nativescript marketplace demo. But its in xml with ts. But I want to achieve this with html and angular.

<TabViewItem ios:title="Stack" iconSource="{{ selectedIndex == 0 ? 'res://stack1' : 'res://stack' }}"> <TabViewItem.view>

Thanks!

Hey, @praven07

You can simply bind to your *tabItem using the angular binding syntax but bind the whole object passed for your taItem. Note that when you want to change the context, you should update not only the key of your object(e.g. iconSource) but the whole object.
e.g
page.component.html.

<TabView iosIconRenderingMode="alwaysTemplate" selectedTabTextColor="green">
        <StackLayout *tabItem="myTabItem" >
            <Label text="First tap" textWrap="true"></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>

and in your code behind file
page.component.ts

export class PageComponent {
    public myTabItem: any;

    constructor() { 
        this.myTabItem  = { title: "NativeScript", iconSource: "~/images/logo.png" };
    }
}

That said now you can implement further logic and load the proper tabItem object depending on some additional logic.

Please keep in mind that this repository is fo reporting issues and bugs and logic and UI related questions are better suited for our community channels such as StackOverflow and forum.nativescript.org (where you will receive faster answers and your information will be visible fot the whole NativeScript community)

Hi nicklliev,
I am trying to use your solution. I am trying to change the myTabItem on selectedIndexChanged. For some reason the *tabItem binding change does not seem to show up on the UI.
my html:

<TabView [(ngModel)]="tabSelectedIndex"  (selectedIndexChanged)="tabViewIndexChange($event)"  selectedColor="#6b8cc8" >
   <StackLayout *tabItem="{title: 'Stats'}">
     <Label text="First tab item"></Label>

    </StackLayout>
  <StackLayout *tabItem="appStoreTabItem">
        <!--<Label text="Second tab item"></Label>-->
        <appStoreHome></appStoreHome>
    </StackLayout>

</TabView>

My ts file:

 tabViewIndexChange(args){
        console.log("tab index:"+ args.newIndex);

        if(args.newIndex == 1){
             this.appStoreTabItem = {title: "Appz", iconSource: "res://apps-active" };
            console.log("tab selected");

        }
    }

I am stuck trying to update the tabview items icon on active state. Any help would be much appreciated. Thank you.

Hello,
@NickIliev I'm having the same issue described by @vikramadityas . Any solution for this issue?

HI @vikramadityas @ajaysurve9,
Indeed the tabItem binding will not work. This is a known issue, which is already logged here.

Hello,
@NickIliev @tsonevn @vikramadityas
Is there a fix or workaround for tabItem binding issue?

Hi guys,
I found a solution for me.

I use two different icons for the selection state and for the inactive state.
Also property iosIconRenderingMode value should be "alwaysOriginal".

In template:

<TabView tabBackgroundColor="#6E7AFA" androidTabsPosition="bottom" iosIconRenderingMode="alwaysOriginal" (selectedIndexChanged)="tabViewIndexChange($event)">
    <page-router-outlet *tabItem="homeTab" name="homeTab"></page-router-outlet>
    <page-router-outlet *tabItem="settingsTab" name="settingsTab"></page-router-outlet>
</TabView>

In component:

homeTab: any;
settingsTab: any;

constructor() {
    this.homeTab  = { iconSource: this.getIconSource("home") };
    this.settingsTab  = { iconSource: this.getIconSource("settings") };
}

tabViewIndexChange(args) {
    const index = args.newIndex;
    this.homeTab = { iconSource: this.getIconSource(index === 0 ? "home_selected" : "home") };
    this.settingsTab = { iconSource: this.getIconSource(index === 1 ? "settings_selected" : "settings") };
}

getIconSource(icon: string): string {
    const iconPrefix = isAndroid ? "res://" : "res://tabIcons/";
    return iconPrefix + icon;
}

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NickIliev picture NickIliev  路  58Comments

dbbk picture dbbk  路  54Comments

mspusta78 picture mspusta78  路  59Comments

valentinstoychev picture valentinstoychev  路  79Comments

morningrat picture morningrat  路  67Comments