4
votes

How to set the default selected Tab inside the tab bar on Xamarin forms shell?

<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         x:Class="TestApp.NavigationShell"
         xmlns:pages="clr-namespace:TestApp.Pages"
         xmlns:pageModels="clr-namespace:TestApp.PageModels">
<TabBar Route="testapp">
    <Tab Title="Saved" Icon="tabDashboard" Route="dashboard"><ShellContent ContentTemplate="{DataTemplate pages:DashBoardPage}"/></Tab>
    <Tab Title="Calendar" Icon="tabCalendar" Route="calendar"><ShellContent ContentTemplate="{DataTemplate pages:CalendarPage}"/></Tab>
    <Tab Title="Search" Icon="tabSearch" Route="search"><ShellContent ContentTemplate="{DataTemplate pages:SearchPage}"/></Tab>
    <Tab Title="Support" Icon="tabSupport" Route="support"><ShellContent ContentTemplate="{DataTemplate pages:SupportPage}"/></Tab>
    <Tab Title="Profile" Icon="tabAccount" Route="account"><ShellContent ContentTemplate="{DataTemplate pages:AccountPage}"/></Tab>
</TabBar>

According to the Xamarin Forms documentation, the first Shell Content will be the default content on the screen. However; I'm trying to set the "Search" page as the default tab rather than "Saved".

I tried to set Tab Index - no luck I also tried to call routing on onAppearing method of Shell but seems like Shell's on appearing method never gets fired.

I tried to navigate to Search as well:

public partial class NavigationShell : Shell
{
    public NavigationShell()
    {
        InitializeComponent();
        //Shell.Current.TabIndex = 2;
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        //await Shell.Current.GoToAsync("testapp/search");
    }
}

What could be the best solution that when app opens need to set the default tab?

Thank you.

3

3 Answers

2
votes

Here, how I fix it by using the Name field attribute.

I assigned the name to the TabBar and the tab which I want to assign in the first place.

AppShell.xaml

<TabBar x:Name="main_tab_bar" Route="main">

    <Tab Title="History">
        <Tab.Icon>
            <FontImageSource FontFamily="MaterialIconsRegular" Glyph="{x:Static Emojis:MaterialRegFont.List}"/>
        </Tab.Icon>
        <ShellContent ContentTemplate="{DataTemplate Views:CallLogPage}" />
    </Tab>

    <Tab x:Name="main_tab_bar_dial"  Title="Dial" >
        <Tab.Icon>
            <FontImageSource FontFamily="MaterialIconsRegular" Glyph="{x:Static Emojis:MaterialRegFont.Dialpad}"/>
        </Tab.Icon>
        <ShellContent ContentTemplate="{DataTemplate Views:MainDialerPage}" />
    </Tab>

    <Tab Title="Settings">
        <Tab.Icon>
            <FontImageSource FontFamily="MaterialIconsRegular" Glyph="{x:Static Emojis:MaterialRegFont.Settings}"/>
        </Tab.Icon>
        <ShellContent ContentTemplate="{DataTemplate Views:MainSettingsPage}" />
    </Tab>

</TabBar>

AppShell.cs

public AppShell() {
    InitializeComponent(); 
    Init();
}

private void Init() {
    main_tab_bar.CurrentItem = main_tab_bar_dial;
}
0
votes

Nevermind, I think I found a solution.

public Page Init(Shell root)
{
    CurrentShell = root;
    root.CurrentItem.CurrentItem = root.CurrentItem.Items[2];
    return CurrentShell;
}

Becase my shell have ONLY one root item which is tabbar itself. I just get the search tab and assigned to the first child's current item and it worked.

Please post your answers if you found another way around. Thank you.

0
votes

On the constructor of your Shell class you can set the CurrentItem

in my case I have an <ShellItem> with some <tab>

public PrivateShell()
{
    InitializeComponent();
    this.CurrentItem.CurrentItem = homeTab; //tab defined by x:Name on XAML
}

As far as I could check it does not pre-render the first shellcontent in case you're using ContentTemplate pattern