Hamburger Menu Xamarin Forms (MasterDetailPage)

18,351

Solution 1

  • Creating the master-detail page:

Add a content page and change the code as follows :

RootPage.xaml

<?xml version="1.0" encoding="utf-8"?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" 
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              xmlns:local="clr-namespace: your_NameSpace"
              x:Class="your_NameSpace.RootPage">
</MasterDetailPage>

RootPage.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPage : MasterDetailPage
{
    public RootPage()
    {                        
        InitializeComponent();
    }
}
  • Creating its Menu Page:

Add another content page and change the code as follows :

MenuPage.xaml (Design of the actual hamburger menu)

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage BackgroundColor="White"
         xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         x:Class="your_NameSpace.MenuPage">
<ContentPage.Padding >
    <OnPlatform x:TypeArguments="Thickness" iOS=" 0 , 20 , 0 , 0" />
</ContentPage.Padding>  
<ContentPage.Content>
    <StackLayout BackgroundColor="White" Padding ="10 , 30 , 10, 10">
        <Button Text="Login" BackgroundColor="White" TextColor="DarkGray" HorizontalOptions="StartAndExpand" Command="{Binding GoHomeCommand}" />
        <BoxView HeightRequest="0.5" HorizontalOptions="FillAndExpand" BackgroundColor="Gray"/>            
        <Button Text="Search" BackgroundColor="White" TextColor="DarkGray" HorizontalOptions="StartAndExpand" Command="{Binding GoSecondCommand}" />
        <BoxView HeightRequest="0.5" HorizontalOptions="FillAndExpand" BackgroundColor="Gray"/>
        <Button Text="Browse" TextColor="DarkGray" BackgroundColor="White" HorizontalOptions="StartAndExpand" Command="{Binding GoThirdCommand}"/>
        <BoxView HeightRequest="0.5" HorizontalOptions="FillAndExpand" BackgroundColor="Gray"/>
    </StackLayout>
</ContentPage.Content>

MenuPage.xaml.cs

 [XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MenuPage : ContentPage
{
    public MenuPage()
    {
        BindingContext = new MenuPageViewModel();
        this.Icon = "yourHamburgerIcon.png"; //only neeeded for ios
        InitializeComponent();
    }
}
  • Its model class :

This is where the button click commands of the menu page are bound in

MenuPageViewModel.cs

 public class MenuPageViewModel
{
    public ICommand GoHomeCommand { get; set; }
    public ICommand GoSecondCommand { get; set; }
    public ICommand GoThirdCommand { get; set; }
    public MenuPageViewModel()
    {
        GoHomeCommand = new Command(GoHome);
        GoSecondCommand = new Command(GoSecond);
        GoThirdCommand = new Command(GoThird);
    }

    void GoHome(object obj)
    {
        App.NavigationPage.Navigation.PopToRootAsync();
        App.MenuIsPresented = false;
    }

    void GoSecond(object obj)
    {
        App.NavigationPage.Navigation.PushAsync(new Home()); //the content page you wanna load on this click event 
        App.MenuIsPresented = false;
    }

    void GoThird(object obj)
    {
        App.NavigationPage.Navigation.PushAsync(new ClinicInformation());
        App.MenuIsPresented = false;
    }
}
  • Add the following properties in your application class usually, the name for your application class is App.xaml and App.xaml.cs

Add the following to your App.xaml.cs:

    public static NavigationPage NavigationPage { get; private set; }
    public static RootPage RootPage;
    public static bool MenuIsPresented
    {
        get
        {
            return RootPage.IsPresented;
        }
        set
        {
            RootPage.IsPresented = value;
        }
    }

Here RootPage is a static instance of your master-detail page, NavigationPage is your detail page that you change to change your detail page, IsMenuPresentend is the bool than when true keeps the MenuPage open and when false closes the same.

  • After doing all this add this function in your application class and call it in its constructor of your App.Xaml.cs

     private void CallMain()
     {
        var menuPage = new MenuPage();
        NavigationPage = new NavigationPage(new Home());
        RootPage = new RootPage();
        RootPage.Master = menuPage;
        RootPage.Detail = NavigationPage;
        MainPage = RootPage;
     }
    
  • In your Android project add the following theme:

values/styles.xml

<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme" parent="MyTheme.Base">
</style>

<style name="DrawerArrowStyle" 
parent="@style/Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
 <item name="color">#FFFFFF</item>
</style>

<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">#003399</item>
<item name="colorPrimaryDark">#003399</item>
<item name="colorControlHighlight">#003399</item>
<item name="colorAccent">#012348</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

</resources>
  • Create a folder named values-v21 and add an XML named styles.xml and add the following code to it :

     <?xml version="1.0" encoding="utf-8" ?>
     <resources>
     <style name="MyTheme" parent="MyTheme.Base">
     <item name="android:windowContentTransitions">true</item>
     <item name="android:windowAllowEnterTransitionOverlap">true</item>
     <item name="android:textAllCaps">false</item>
     <item name="android:windowAllowReturnTransitionOverlap">true</item>
     <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
     <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
     </style>
     </resources>
    

And use the name myTheme as the app theme in all your Android activities.

There you go your hamburger menu is complete in case you have any queries feel free to comment.

Good luck!

Happy Coding.

Solution 2

You can try this as well for detailed information

Hamburger Menu tutorial

enter image description here

Share:
18,351

Related videos on Youtube

Riccardo Pezzolati
Author by

Riccardo Pezzolati

Updated on September 15, 2022

Comments

  • Riccardo Pezzolati
    Riccardo Pezzolati over 1 year

    I'm new enough to use Xamarin, in my Xamarin Forms project I created a Master-Detail Page and in the ListView that represents the menu I wanted to put Title and Icon, for icon images I have to insert each icon in all device projects?

    And I also have a small problem, when I click on a menu item and navigate to the selected Detail page, the hamburger menu disappears

    MainPageMaster.xaml

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="XXX"
                 Title="Master">
      <StackLayout>
        <ListView x:Name="MenuItemsListView"
                  SeparatorVisibility="None"
                  HasUnevenRows="true"
                  ItemsSource="{Binding MenuItems}">
          <ListView.Header>
            <Grid BackgroundColor="#03A9F4">
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="6"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="6"/>
              </Grid.ColumnDefinitions>
              <Grid.RowDefinitions>
                <RowDefinition Height="15"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="10"/>
              </Grid.RowDefinitions>
              <Label
                  Grid.Column="1"
                  Grid.Row="1"
                  Text="B1 Term"
                  HorizontalTextAlignment="Center"
                  Style="{DynamicResource SubtitleStyle}"/>
            </Grid>
          </ListView.Header>
          <ListView.ItemTemplate>
            <DataTemplate>
              <ViewCell>
                  <StackLayout VerticalOptions="FillAndExpand"
                                 Orientation="Horizontal"
                                 Padding="20,10,0,10"
                                 Spacing="20">
                                <Image Source="{Binding Icon}"
                             WidthRequest="40"
                             HeightRequest="40"
                             VerticalOptions="Center" />
                                <Label Text="{Binding Title}"
                             FontSize="Medium"
                             VerticalOptions="Center"
                             TextColor="Black"/>
                </StackLayout>
              </ViewCell>
            </DataTemplate>
          </ListView.ItemTemplate>
        </ListView>
      </StackLayout>
    </ContentPage>
    

    File .cs

    [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class MainPageMaster : ContentPage
        {
            public ListView ListView;
    
            public MainPageMaster()
            {
                InitializeComponent();
    
                BindingContext = new MainPageMasterViewModel();
                ListView = MenuItemsListView;
            }
    
            class MainPageMasterViewModel : INotifyPropertyChanged
            {
                public ObservableCollection<MainPageMenuItem> MenuItems { get; set; }
    
                public MainPageMasterViewModel()
                {
                    MenuItems = new ObservableCollection<MainPageMenuItem>(new[]
                    {
                        new MainPageMenuItem { Id = 0, Icon="ic_menu_home.png",Title = "Home", TargetType = typeof(MainPageDetail) },
                        new MainPageMenuItem { Id = 1, Title = "Elenco Clienti", TargetType = typeof(ElencoClientiPage) },
                        new MainPageMenuItem { Id = 2, Title = "Logout", TargetType = typeof(LogOut) }
                    });
                }
    
                #region INotifyPropertyChanged Implementation
                public event PropertyChangedEventHandler PropertyChanged;
                void OnPropertyChanged([CallerMemberName] string propertyName = "")
                {
                    if (PropertyChanged == null)
                        return;
    
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
                }
                #endregion
            }
        }
    

    Screen

    enter image description here

    In this image, my icon isn't visible but I add an image in Android project