.NET MAUI - Menu de navegação Flyout


 Hoje veremos como um menu para navegação usando o Shell do .NET MAUI.

O .NET MAUI é de código aberto e é a evolução do Xamarin.Forms, estendido de cenários móveis a desktops, com controles de IU reconstruídos do zero para desempenho e extensibilidade.

Se você já usou o Xamarin.Forms anteriormente para criar aplicações multiplataforma, você notará muitas semelhanças com o .NET MAUI.

Apresentando o Shell

O Shell do .NET MAUI é um recurso que reduz a complexidade do desenvolvimento de aplicativos fornecendo os recursos fundamentais que a maioria dos aplicativos exige, incluindo:

O Shell é baseado em flyout ou submenus  e tabs ou guias. O nível superior de navegação em um aplicativo Shell é um flyout ou submenu ou uma tab bar ou barra de guias inferior, dependendo dos requisitos de navegação do aplicativo. Quando a experiência de navegação de um aplicativo começa com guias inferiores, o filho do objeto Shell com subclasse deve ser um objeto TabBar, que representa a barra de guias inferior.

Assim, a experiência de navegação fornecida pelo Shell é baseada em submenus e guias. Um submenu é o menu raiz opcional para um aplicativo Shell e é totalmente personalizável. É acessível através de um ícone ou deslizando na lateral da tela. O submenu consiste em um cabeçalho opcional, itens de submenu, itens de menu opcionais e um rodapé opcional.

Um ou mais itens de submenu podem ser adicionados ao submenu e cada item de submenu é representado por um objeto FlyoutItem. Cada objeto FlyoutItem deve ser um filho do objeto Shell com subclasse. Os itens de submenu aparecem na parte superior do submenu quando um cabeçalho de submenu não está presente.

Criando o projeto Net MAUI e usando Flyout

Neste artigo vamos criar um menu de navegação usando Flyout em um projeto .NET Maui criado no VS 2022 Preview com o nome MauiApp_Flyout.

Vamos incluir na pasta Resources/Images do projeto as imagens que iremos usar nas páginas :

Com o projeto criado vamos criar uma pasta Pages no projeto e nesta pasta vamos criar 8 Views do tipo  tipo .NET MAUI ContentPage(XAML) :

  1. HomePage.xaml
  2. AlteraPage.xaml
  3. CadastroPage.xaml
  4. DeletaPage.xaml
  5. AdicionaPage.xaml

Todas as páginas do tipo ContentPage irão apenas exibir um texto para identificar a página e o código vai ser igual alterando apenas o texto. Assim abaixo temos o código da HomePage.xaml :

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp_Flyout.Pages.HomePage"
             Title="HomePage">
    <VerticalStackLayout>
        <Label
            Text="Home"
            FontSize="Large"
            VerticalOptions="Center"
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentPage>

Assim todas as demais páginas terão o mesmo código , alterando somente a propriedade Text da Label.

A seguir vamos criar 2 Views do tipo .NET MAUI ContentView(XAML):

  1. FlyoutHeader.xaml
  2. FlyoutFooter.xaml   

A página FlyoutHeader.xaml vai ser usada para exibir o Header ou Cabeçalho do menu de opções na navegação e possui o seguinte código:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp_Flyout.Pages.FlyoutHeader">

    <Grid BackgroundColor="Black">

        <Image Aspect="AspectFill"
               Source="store1.jpg"
               Opacity="0.6" />

        <Label Text="Vendas"
               TextColor="White"
               FontAttributes="Bold"
               FontSize="20"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />
    </Grid>
</ContentView>
 

A página FlyoutFooter.xaml vai ser usada para exibir o Rodapé ou Footer do menu de opções na navegação e possui o seguinte código:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              xmlns:sys="clr-namespace:System;assembly=netstandard"
             x:Class="MauiApp_Flyout.Pages.FlyoutFooter">
    <StackLayout BackgroundColor="Gray">

        <Label Text="Copyright - Store"
               TextColor="White"
               FontAttributes="Bold"
               HorizontalOptions="Center" />

        <Label Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='{0:dd MM yyyy}'}"
               TextColor="White"
               HorizontalOptions="Center" />

    </StackLayout>
</ContentView>
 

Agora vamos incluir no arquivo App.xaml o código onde vamos definir a criação das guias usando o Shell e a TabBar:

<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiApp_Guias.Pages"
             x:Class="MauiApp_Guias.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
  

 <Application.MainPage>
        <Shell FlyoutBehavior="Flyout" FlyoutHeaderBehavior="Fixed" FlyoutVerticalScrollMode="Auto">
            <FlyoutItem Title="Home" Icon="home1.jpg">
                <ShellContent ContentTemplate="{DataTemplate local:HomePage}"/>
             </FlyoutItem>
            <FlyoutItem Title="Cadastro" Icon="cadastro1.jpg">
                <ShellContent ContentTemplate="{DataTemplate local:CadastroPage}"/>
            </FlyoutItem>
            <FlyoutItem Title="Adicionar" Icon="adicionar1.jpg">
                <ShellContent ContentTemplate="{DataTemplate local:AdicionaPage}"/>
            </FlyoutItem>
            <FlyoutItem Title="Alterar" Icon="alterar1.jpg">
                <ShellContent ContentTemplate="{DataTemplate local:AlteraPage}"/>
            </FlyoutItem>
            <FlyoutItem Title="Excluir" Icon="excluir1.jpg">
                <ShellContent ContentTemplate="{DataTemplate local:DeletaPage}"/>
            </FlyoutItem>
            <FlyoutItem Title="Configurar" Icon="config1.jpg">
                <ShellContent ContentTemplate="{DataTemplate local:ConfigPage}"/>
            </FlyoutItem>
        </Shell>

    </Application.MainPage>   

</Application>

Para este código funcionar temos que comentar o código em App.xaml.cs que invoca a AppShell:

public partial class App : Application
{
    public App()
    {
InitializeComponent();
//MainPage = new AppShell();
     }
}

Neste código define os itens do menu de navegação com os seus ícones e aciona as respectivas Views definidas na pasta Pages:

Podemos incluir o cabeçalho e o rodapé incluindo o código abaixo:

<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiApp_Guias.Pages"
             x:Class="MauiApp_Guias.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
  

 <Application.MainPage>
        <Shell FlyoutBehavior="Flyout" FlyoutHeaderBehavior="Fixed" FlyoutVerticalScrollMode="Auto">

                       <Shell.FlyoutHeader>
                <local:FlyoutHeader />
            </Shell.FlyoutHeader>

            <Shell.FlyoutFooter>
                <local:FlyoutFooter />
            </Shell.FlyoutFooter>
           ...  
           ...  

        </Shell>

    </Application.MainPage>   

</Application>

Agora teremos o seguinte resultado:

Podemos alterar a aparência dos ícones e seus textos usando o código abaixo:

<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiApp_Guias.Pages"
             x:Class="MauiApp_Guias.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
  

 <Application.MainPage>
        <Shell FlyoutBehavior="Flyout" FlyoutHeaderBehavior="Fixed" FlyoutVerticalScrollMode="Auto">
           <Shell.FlyoutHeader>
                <local:FlyoutHeader />
            </Shell.FlyoutHeader>

            <Shell.FlyoutFooter>
                <local:FlyoutFooter />
            </Shell.FlyoutFooter>

             <Shell.ItemTemplate>
                <DataTemplate>
                    <Grid ColumnDefinitions="0.25*,0.75*" Padding="0,10">
                        <Image Source="{Binding FlyoutIcon}"
                               Margin="5"
                               HeightRequest="45"
                               HorizontalOptions="Center"/>
                        <Label Grid.Column="1"
                               Text="{Binding Title}"
                               FontSize="Small"
                               FontAttributes="Bold"
                               VerticalOptions="Center"/>
                    </Grid>
                </DataTemplate>
            </Shell.ItemTemplate>

           ...  
           ...  

        </Shell>

    </Application.MainPage>   

</Application>

Agora teremos o seguinte resultado:

Para organizar melhor o código podemos criar na pasta Pages uma .NET MAUI ContentPage chamada MenuPage. A seguir basta alterar o tipo ContentPage para Shell no arquivo .xaml e no arquivo xaml.cs, e a seguir podemos mover o código definido em App.xaml para esta view:

<?xml version="1.0" encoding="utf-8" ?>
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiApp_Flyout.Pages"
             x:Class="MauiApp_Flyout.Pages.MenuPage"
             Title="MenuPage">   

    <Shell.FlyoutHeader>
        <local:FlyoutHeader />
    </Shell.FlyoutHeader>

    <Shell.FlyoutFooter>
        <local:FlyoutFooter />
    </Shell.FlyoutFooter>

    <FlyoutItem Title="Home" Icon="home1.jpg">
        <ShellContent ContentTemplate="{DataTemplate local:HomePage}"/>
    </FlyoutItem>
    <FlyoutItem Title="Cadastro" Icon="cadastro1.jpg">
        <ShellContent ContentTemplate="{DataTemplate local:CadastroPage}"/>
    </FlyoutItem>
    <FlyoutItem Title="Adicionar" Icon="adicionar1.jpg">
        <ShellContent ContentTemplate="{DataTemplate local:AdicionaPage}"/>
    </FlyoutItem>
    <FlyoutItem Title="Alterar" Icon="alterar1.jpg">
        <ShellContent ContentTemplate="{DataTemplate local:AlteraPage}"/>
    </FlyoutItem>
    <FlyoutItem Title="Excluir" Icon="excluir1.jpg">
        <ShellContent ContentTemplate="{DataTemplate local:DeletaPage}"/>
    </FlyoutItem>
    <FlyoutItem Title="Configurar" Icon="config1.jpg">
        <ShellContent ContentTemplate="{DataTemplate local:ConfigPage}"/>
    </FlyoutItem>

</Shell>

Agora vamos alterar o código no arquivo App.xaml.cs para definir a MainPage como sendo a MenuPage:

using MauiApp_Flyout.Pages;

namespace MauiApp_Flyout;

public partial class App : Application
{
   public App()
   {
     InitializeComponent();
     MainPage = new MenuPage();
    }
}

Aguarde mais novidades e novos artigos sobre o Net. MAUI.

Pegue o projeto aqui:  MauiApp_Flyout.zip  (sem as referências...)

"Jesus dizia, pois, aos judeus que criam nele: Se vós permanecerdes na minha palavra, verdadeiramente sereis meus discípulos;"
João 8:31

Referências:


José Carlos Macoratti