Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

xamarin.forms - Hamburger Menu Xamarin Forms (MasterDetailPage)

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

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  • 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...