所谓 UWP 样式的布加勒斯特菜单,小编曾经在“张欢欣的 UWP
开拓笔记:亚特兰大菜单进级
”里说过,也正是利用
Segoe MDL2 Assets 字体作为侧面 Icon,何况左边使用填充颜色的矩形用来代表
ListView 的选中。如下图

爱博体育投注 1

  但哪些通过 Xamarin.Forms ,将这一体制的秘Luli马菜单带入到 Android 与 iOS
中吗?

 

  一、大纲-细节形式简要介绍

  讲代码前率先来讲说这种导航航空模型型式,官方称“大纲-细节形式”(MasterDetail)。右侧的埃及开罗菜单称为“大纲”(Master),侧边的页面称为“细节”(Detail)。Xamarin.Froms
为品种提供了若干种导航航空模型型式,“大纲-细节”为内部一种。

 

  二、项目简单介绍

  效果图:

爱博体育投注 2

  非常少说废话,看代码实在些。

  本示例是利用 Visual Studio 2017 创立的 Cross-Platform
项目,项目名称为”HamburgerMenu德姆o“,模板为空白项目。(GitHub:https://github.com/ZhangGaoxing/xamarin-forms-demo/tree/master/HamburgerMenuDemo

爱博体育投注 3

  待项目创制完结后,解决方案共富含多少个门类:分享代码项目、 Android
项目、 iOS 项目、 UWP
项目。分享代码项目为寄存共享页面包车型地铁地点,个人以为和类库依然有一点点分其余。

爱博体育投注 4

  

  三、分享代码项目
HamburgerMenu德姆o 

  首先增加多少个页面,根目录下增多多少个 MasterPage.xaml
页面,用于”大纲视图“。增添贰个 Views
文件夹,用于寄存子页面,向当中增多3个分界面:Page1、Page2、Page3。增添三个 MasterPageItem.cs
类。

  1. MasterPageItem.cs

  和 UWP 的布拉格菜单同样,首先要开创一个类,作为导航的种类,用来绑定
ListView 。名字叫 MasterPageItem.cs 。

  里面包车型客车品质有页面包车型地铁标题 Title,左边的Logo Icon,Logo的字体
FontFamily,目标页面 DestPage,还应该有侧面的矩形展现 Selected 与 颜色
Color。由于要贯彻双向绑定,还要完成接口 INotifyPropertyChanged。要留心的是,Color
类型为 Xamarin.Forms 中的。

代码如下

public class MasterPageItem : INotifyPropertyChanged
{
    // 字体路径,用于引入 Segoe MDL2 Assets 字体
    public string FontFamily { get; set; }

    // 字体图标转义
    public string Icon { get; set; }

    // 标题
    public string Title { get; set; }

    // 目的页
    public Type DestPage { get; set; }

    // 用于显示左侧填充矩形,双向绑定
    private bool selected = false;
    public bool Selected
    {
        get { return selected; }
        set
        {
            selected = value;
            this.OnPropertyChanged("Selected");
        }
    }

    // 选中颜色,双向绑定 ( using Xamarin.Forms )
    private Color color = new Color();
    public Color Color
    {
        get { return color; }
        set
        {
            color = value;
            this.OnPropertyChanged("Color");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

  2. MasterPage.xaml

  MasterPage 为”大纲“视图,即侧面显示 ListView
的页面。本项指标 MasterPage 分为两栏,分一流菜单与二级菜单,即置顶一个ListView 与置底一个 ListView 。 ListView 的 ItemTemplate 与 UWP
稍有两样,右侧的填充矩形换来了 BoxView,二级菜单的上方线由 Border
换到了高度为1的 BoxView。代码如下

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HamburgerMenuDemo.MasterPage"
             Icon="hamburger.png"
             Title=" ">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--一级菜单-->
        <ListView x:Name="PrimaryListView" VerticalOptions="StartAndExpand" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <!--BoxView 充当 Border-->
        <BoxView BackgroundColor="Gray" Grid.Row="1" HorizontalOptions="FillAndExpand" />

        <!--二级菜单-->
        <ListView x:Name="SecondaryListView" Grid.Row="2" VerticalOptions="End" SeparatorVisibility="None" Margin="0,-6,0,0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label x:Name="IconLabel" Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>

  MasterPage.xaml.cs 代码也必要讲下,不知是怎么回事,以上 Xaml
代码直接运转时多个菜单会显得不正规,只显示七个美食做法,<RowDefinition
Height=”Auto” /> 在这些 ContentPage
里好像无效。由此作者在后台代码设置了二级菜单的惊人,也正是48 *
secondaryItems.Count。五个 ListView 供给经过性能的方法,向 MainPage
传递控件。字体路线各种品种不一致,要求单独设置,小编背后会说。MasterPage.xaml.cs
代码如下

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MasterPage : ContentPage
{
    // 向 MainPage 传递控件
    public ListView primaryListView { get { return PrimaryListView; } }
    public ListView secondaryListView { get { return SecondaryListView; } }

    public MasterPage()
    {
        InitializeComponent();

        // 设置不同平台的字体路径
        string fontFamily;
        switch (Device.RuntimePlatform)
        {
            case "Android":
                fontFamily = "segmdl2.ttf#Segoe MDL2 Assets";
                break;

            case "iOS":
                fontFamily = "Segoe MDL2 Assets";
                break;

            case "Windows":
                fontFamily = "/Assets/segmdl2.ttf#Segoe MDL2 Assets";
                break;

            case "WinPhone":
                fontFamily = "/Assets/segmdl2.ttf#Segoe MDL2 Assets";
                break;

            default:
                fontFamily = "segmdl2.ttf#Segoe MDL2 Assets";
                break;
        }

        // 列表项
        var primaryItems = new List<MasterPageItem>() {
                new MasterPageItem
                {
                    Title = "Page1",
                    FontFamily = fontFamily,
                    Icon = "\xE10F",
                    Color = Color.DeepSkyBlue,
                    Selected = true,
                    DestPage = typeof(Page1)
                },
                new MasterPageItem
                {
                    Title = "Page2",
                    FontFamily = fontFamily,
                    Icon = "\xE11F",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(Page2)
                },
                new MasterPageItem
                {
                    Title = "Page3",
                    FontFamily = fontFamily,
                    Icon = "\xE12F",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(Page2)
                }
            };

        var secondaryItems = new List<MasterPageItem>() {
                new MasterPageItem
                {
                    Title = "设置",
                    FontFamily = fontFamily,
                    Icon = "\xE713",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(SettingPage)
                },
                new MasterPageItem
                {
                    Title = "关于",
                    FontFamily = fontFamily,
                    Icon = "\xE783",
                    Color = Color.Black,
                    Selected = false,
                    DestPage = typeof(AboutPage)
                }
            };

        // ListView 数据绑定
        PrimaryListView.ItemsSource = primaryItems;
        SecondaryListView.ItemsSource = secondaryItems;

        // 设置二级菜单高度
        SecondaryListView.HeightRequest = 48 * secondaryItems.Count;
    }
}

  3. MainPage.xaml

  下边来修改一下 MainPage.xaml 。MainPage.xaml 为运用的输入页面,可在
App.xaml.cs 中改换。将 MainPage 中的根成分替换为 MasterDetailPage
。注释很详细,不多说了

<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:HamburgerMenuDemo"
             x:Class="HamburgerMenuDemo.MainPage"
             xmlns:views="clr-namespace:HamburgerMenuDemo.Views">

    <!--大纲视图-->
    <MasterDetailPage.Master>
        <!--引入 MasterPage 并给个名称,用于后台设置 MasterPage 传递过来的 ListView-->
        <local:MasterPage x:Name="masterPage" />
    </MasterDetailPage.Master>

    <!--细节视图-->
    <MasterDetailPage.Detail>
        <NavigationPage>
            <x:Arguments>
                <!--默认显示的页面-->
                <views:Page1 />
            </x:Arguments>
        </NavigationPage>
    </MasterDetailPage.Detail>

</MasterDetailPage>

  一样的 MainPage.xaml.cs 中的代码也异常的粗略,注释很详细

public MainPage()
{
    InitializeComponent();

    // ListView 点击事件
    masterPage.primaryListView.ItemSelected += MasterPageItemSelected;
    masterPage.secondaryListView.ItemSelected += MasterPageItemSelected;

    // 设置 Windows 平台的“大纲”显示模式为折叠
    if (Device.RuntimePlatform == Device.Windows)
    {
        MasterBehavior = MasterBehavior.Popover;
    }
}

private void MasterPageItemSelected(object sender, SelectedItemChangedEventArgs e)
{
    var item = e.SelectedItem as MasterPageItem;

    if (item != null)
    {
        // 遍历 ListView 数据源,将选中项矩形显示,字体颜色设置成未选中
        foreach (MasterPageItem mpi in masterPage.primaryListView.ItemsSource)
        {
            mpi.Selected = false;
            mpi.Color = Color.Black;
        }
        foreach (MasterPageItem mpi in masterPage.secondaryListView.ItemsSource)
        {
            mpi.Selected = false;
            mpi.Color = Color.Black;
        }

        // 设置选中项
        item.Selected = true;
        item.Color = Color.DeepSkyBlue;

        // 跳转
        Detail = new NavigationPage((Page)Activator.CreateInstance(item.DestPage));

        // 取消 ListView 默认选中样式
        masterPage.primaryListView.SelectedItem = null;
        masterPage.secondaryListView.SelectedItem = null;

        // 关闭“大纲”
        IsPresented = false;
    }
}

  要专注的是 MasterPage.xaml 页面中的 Title
绝对要给,要否则会报错,能够在后台 cs 文件中期维修改 Title 属性,也足以在
Xaml 根元素中修改 Title。Views 中的多少个页面 Title
不给能够,但标题栏不会来得页面包车型大巴 Title,倒霉看。

 

  四、Android
项目 HamburgerMenuDemo.Android

  1. 字体设置

  将 segmdl2.ttf 字体文件间接选举用入 Assets 文件夹下就能够

  2. 修改 style.xml

  ”大纲“的暗许效果是 DrawerLayout
覆盖状态栏的,不太美貌,须要修改样式。在 style.xml 中增添

<item name="android:fitsSystemWindows">true</item>

  同一时候,由于修改了体制,产生了状态栏覆盖 DrawerLayout
,要求给 MasterPage.xaml 中的根 Grid 赋值贰个 Padding=”0,25,0,-6″,但
UWP 项目却没有必要,这一点作者会在文末给出代码。

 

  五、iOS
项目 HamburgerMenuDemo.iOS

  1. 字体设置

  弄了许久,Xamarin 太坑了,plist 的编辑器很不和谐。。。

  (1)将 segmdl2.ttf 字体文件一向放入 Resources 文件夹

  (2)改动 segmdl2.ttf 属性,复制到输出目录 =》 始终复制,生成操作
=》 BundleResource

  (2)不要双击,右击 Info.plist ,查看代码,增加如下内容

<dict>
    <key>UIAppFonts</key>
    <array>
      <string>segmdl2.ttf</string>
    </array>
  </dict>

  假诺要增多任何的财富,能够友善新建七个 .plist
文件,新建的文本是健康显示财富列表的,增多实现后,复制代码到 Info.plist
就能够。

  2. Padding

  和安卓一样,需求给 MasterPage.xaml 中的根 Grid 赋值三个Padding=”0,20,0,-6″,小编会在文末给出代码。

 

  六、Padding 代码

  在 MasterPage.xaml 增添如下代码

<!--安卓空出状态栏的宽度-->
<ContentPage.Resources>
    <ResourceDictionary>
        <OnPlatform x:Key="padding"
              x:TypeArguments="Thickness"
              iOS="0,20,0,-6"
              Android="0,25,0,-6"
              WinPhone="0" />
    </ResourceDictionary>
</ContentPage.Resources>

  别忘了在 Grid 中引用能源

Padding="{StaticResource padding}"

  MasterPage.xaml 最后代码

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HamburgerMenuDemo.MasterPage"
             Icon="hamburger.png"
             Title=" ">

    <!--安卓空出状态栏的宽度-->
    <ContentPage.Resources>
        <ResourceDictionary>
            <OnPlatform x:Key="padding"
                  x:TypeArguments="Thickness"
                  iOS="0,20,0,0"
                  Android="0,20,0,0"
                  WinPhone="0" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <Grid Padding="{StaticResource padding}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!--一级菜单-->
        <ListView x:Name="PrimaryListView" VerticalOptions="StartAndExpand" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <!--BoxView 充当 Border-->
        <BoxView BackgroundColor="Gray" Grid.Row="1" HorizontalOptions="FillAndExpand" />

        <!--二级菜单-->
        <ListView x:Name="SecondaryListView" Grid.Row="2" VerticalOptions="End" SeparatorVisibility="None" Margin="0,-6,0,0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid HeightRequest="48">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="48"/>
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <BoxView BackgroundColor="{Binding Color}" WidthRequest="5" HeightRequest="26" HorizontalOptions="Start" VerticalOptions="Center" IsVisible="{Binding Selected}" />
                            <Label x:Name="IconLabel" Text="{Binding Icon}" FontFamily="{Binding FontFamily}" TextColor="{Binding Color}" FontSize="16" HorizontalOptions="Center" VerticalOptions="Center" />
                            <Label Grid.Column="1" Text="{Binding Title}" TextColor="{Binding Color}" FontSize="14" VerticalOptions="Center" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage>