365体育网投  所谓 UWP 样式的慕尼黑菜单

  所谓 UWP 样式的杜塞尔多夫菜单,作者以前在“张欢欣的 UWP
开拓笔记:罗马菜单进级
”里说过,相当于应用
Segoe MDL2 Assets 字体作为侧面 Icon,况且侧边使用填充颜色的矩形用来代表
ListView 的选中。如下图

365体育网投 1

  但什么通过 Xamarin.Forms ,将这一体裁的达拉斯菜单带入到 Android 与 iOS
中吗?

 

  一、大纲-细节格局简要介绍

  讲代码前首先来讲说这种导航航空模型型式,官方称“大纲-细节方式”(MasterDetail)。左边的胡志明市菜单称为“大纲”(Master),左边的页面称为“细节”(Detail)。Xamarin.Froms
为品种提供了多少种导航航空模型型式,“大纲-细节”为内部一种。

 

  二、项目简要介绍

  效果图:

365体育网投 2

  没有多少说废话,看代码实在些。

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

365体育网投 3

  待项目创设完结后,应用方案共包罗多少个项目:分享代码项目、 Android
项目、 iOS 项目、 UWP
项目。分享代码项目为贮存分享页面包车型大巴地点,个人感到和类库照旧有一点点分别的。

365体育网投 4

  

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

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

  1. MasterPageItem.cs

  和 UWP 的开普敦菜单一样,首先要创立一个类,作为导航的品类,用来绑定
ListView 。名字叫 MasterPageItem.cs 。

  里面包车型大巴本性有页面的标题 Title,左侧包车型地铁图标 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>