xamarin.formsxamarin.shell

Adding a shell flyout item header


In Xamarin Shell I'm trying to add a header to a flyout item. See the picture below (taken from the Xaminals project).

The 'Categories' text is a header which is not clickable or navigatable, just a static template.

I have found an article here but it's without source code and I haven't been able to construct a working example.

How can I achieve something like this?

enter image description here


Solution

  • I managed to figure out a solution, so I'll put it here in case anyone wants something similar.

    1. Add a FlyoutItemTemplateSelector. This class will be responsible for rendering a regular flyout item or a header template.

      public class FlyoutItemTemplateSelector : DataTemplateSelector
      {
          public DataTemplate NavigationHeaderTemplate { get; set; }
          public DataTemplate NavigationItemTemplate { get; set; }
      
          protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
          { 
              if (item is ShellGroupItem && ((ShellGroupItem)item).Title == "Header")
              {
                  // Make sure a header item is not clickable.
                  ((ShellGroupItem)item).IsEnabled = false;
                  return NavigationHeaderTemplate;
              }
              else
                  return NavigationItemTemplate;
          }
      }
      
    2. Add the regular ItemTemplate, the new Header template and the FlyoutItemTemplateSelector control to the Shell.Resources tag in AppShell.xaml:

      <Shell.Resources>
          <ResourceDictionary>
              <DataTemplate x:Key="FlyoutItemTemplate">
                  <Grid>
                      <Grid.ColumnDefinitions>
                          <ColumnDefinition Width="0.25*" />
                          <ColumnDefinition Width="0.75*" />
                      </Grid.ColumnDefinitions>
                      <Label Text="{Binding Icon}"
                             FontFamily="{StaticResource MaterialFontFamily}"
                             HeightRequest="45"
                             Margin="20,0,0,0"
                             FontSize="30"
                             TextColor="Black"
                             VerticalTextAlignment="Center" />
                      <Label Grid.Column="1"
                             Text="{Binding Title}"
                             TextColor="Black"
                             VerticalTextAlignment="Center" />
                  </Grid>
              </DataTemplate>
              <DataTemplate x:Key="FlyoutHeaderTemplate">
                  <StackLayout Orientation="Vertical">
                      <Label HeightRequest="35"
                             Margin="20,0,0,0"
                             Text="{Binding Title}"
                             TextColor="Black"
                             VerticalTextAlignment="Center" />
                  </StackLayout>
              </DataTemplate>
      
              <controls:FlyoutItemTemplateSelector
                  x:Key="FlyoutTemplateSelector"
                  NavigationHeaderTemplate="{StaticResource FlyoutHeaderTemplate}"
                  NavigationItemTemplate="{StaticResource FlyoutItemTemplate}" />
          </ResourceDictionary>
      </Shell.Resources>
      
    3. Add the Shell.ItemTemplate to the main Shell tag:

      <Shell
          ...
          Shell.ItemTemplate="{StaticResource FlyoutTemplateSelector}"
      >
      
    4. Add the item for the header:

      <ShellContent Title="Header" ContentTemplate="{DataTemplate local:AboutPage}" />
      

    Result:

    enter image description here

    Some notes:

    Like this, we can also define other templates, like a footer containing your app version, or a copyright text, etc...

    Hope this helps anyone.