博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )...
阅读量:7251 次
发布时间:2019-06-29

本文共 8494 字,大约阅读时间需要 28 分钟。

  所谓 UWP 样式的汉堡菜单,我曾在“”里说过,也就是使用 Segoe MDL2 Assets 字体作为左侧 Icon,并且左侧使用填充颜色的矩形用来表示 ListView 的选中。如下图

  但怎样通过 Xamarin.Forms ,将这一样式的汉堡菜单带入到 Android 与 iOS 中呢?

 

  一、大纲-细节模式简介

  讲代码前首先来说说这种导航模式,官方称“大纲-细节模式”(MasterDetail)。左侧的汉堡菜单称为“大纲”(Master),右侧的页面称为“细节”(Detail)。Xamarin.Froms 为项目提供了若干种导航模式,“大纲-细节”为其中一种。

 

  二、项目简介

  效果图:

  不多说废话,看代码实在些。

  本示例是使用 Visual Studio 2017 创建的 Cross-Platform 项目,项目名为”HamburgerMenuDemo“,模板为空白项目。(GitHub:)

  待项目创建完成后,解决方案共包含四个项目:共享代码项目、 Android 项目、 iOS 项目、 UWP 项目。共享代码项目为存放共享页面的地方,个人觉得和类库还是有点区别的。

  

  三、共享代码项目 HamburgerMenuDemo 

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

  1. MasterPageItem.cs

  和 UWP 的汉堡菜单一样,首先要创建一个类,作为导航的项目,用来绑定 ListView 。名字叫 MasterPageItem.cs 。

  里面的属性有页面的标题 Title,左侧的图标 Icon,图标的字体 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。代码如下

  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
() { 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
() { 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 。注释很详细,不多说了

  同样的 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 中添加

true

  同时,由于修改了样式,变成了状态栏覆盖 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 ,查看代码,添加如下内容

UIAppFonts
segmdl2.ttf

  如果要添加其他的资源,可以自己新建一个 .plist 文件,新建的文件是正常显示资源列表的,添加完成后,复制代码到 Info.plist 即可。

  2. Padding

  和安卓一样,需要给 MasterPage.xaml 中的根 Grid 赋值一个 Padding="0,20,0,-6",我会在文末给出代码。

 

  六、Padding 代码

  在 MasterPage.xaml 添加如下代码

  别忘了在 Grid 中引用资源

Padding="{StaticResource padding}"

  MasterPage.xaml 最终代码

 

转载地址:http://lzebm.baihongyu.com/

你可能感兴趣的文章
从浏览器渲染的角度谈谈html标签的语义化
查看>>
文件权限及特殊权限管理SUID、SGID和Sticky
查看>>
iis 7 asp.net ajax post 请求字节过大报错问题解决办法
查看>>
高仿腾讯QQ即时通讯IM项目
查看>>
winform 中xml简单的创建和读取
查看>>
活动设计的“七宗罪”(转)
查看>>
如何在ChemDraw中输入℃温度符号
查看>>
SSH-Struts第二弹:一个Form提交两个Action
查看>>
词法分析
查看>>
Linux命令(二)
查看>>
Web登录验证之 Shiro
查看>>
LeeCode-Sort Colors
查看>>
Snort2.9.2.3 Installation on CentOS 6.2
查看>>
我的友情链接
查看>>
给软件工程师的自学建议
查看>>
Linux下SVN的备份方式
查看>>
hadoop 3.0.0 alpha1 分布式搭建
查看>>
刘宇凡:从吃饭中的道理领悟SEO
查看>>
1.1办公软件概述
查看>>
python中http的一些编码转换
查看>>