【问题标题】:MvvmCross sidebar navigation for MvvmCross 5.xMvvmCross 5.x 的 MvvmCross 侧边栏导航
【发布时间】:2017-11-13 19:31:04
【问题描述】:

我想同时为我的应用实现两种导航方式,侧边栏导航和父子导航。 我的应用以汉堡(侧边栏)菜单开头。

侧边栏菜单中的第一项应重置导航堆栈并打开主视图。 主视图控制器应启动根堆栈导航,因此主视图上的每个按钮都应打开一个新视图,新视图上的按钮应打开另一个视图等。

侧边栏菜单中的每个其他项目都应以对话框的形式打开一个新视图。

我使用的是 MvvmCross 5.x,没有与 5.x 版本兼容的示例。 有没有人可以指点我一个可用的样本?

【问题讨论】:

    标签: navigation mvvmcross sidebar flyout


    【解决方案1】:

    首先我假设您正在尝试为 iOS 实现此功能。如果是 Android,您可以简单地使用 Navigation Drawer。

    iOS 上的示例尚未转换为 MvvmCross 5.x(我将立即开始这样做),但这应该是微不足道的。让我试着引导你完成它:

    1. 确保将 MvvmCross iOS 支持包添加到您的 iOS 项目中:Install-Package MvvmCross.iOS.Support -Version 5.0.2(或使用 GUI)
    2. 通过将以下代码添加到 iOS 项目中的 Setup 类,将您的 iOS 项目配置为使用 MvxSidebarPresenter

      protected override IMvxIosViewPresenter CreatePresenter()
      {
          return new MvxSidebarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
      }
      
    3. 创建一个视图控制器,作为弹出菜单并用MvxSidebarPresentationAttribute 装饰它。此视图控制器将充当您的菜单。您可以(或更好地应该)将其链接到将处理导航部分的视图模型(当用户选择菜单项时)。这个视图控制器可能看起来像这样:

      [MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
      public class LeftPanelView : MvxViewController<LeftPanelViewModel>
      {
          ...
      }
      
    4. 要确保您的主视图充当根控制器,只需将MvxSidebarPresentationAttribute 添加到主视图控制器并确保属性Panel 设置为CenterHintType 设置为ResetRootShowPanel 设置为 true),如下所示:

      [MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
      public class HomeView : MvxViewController<HomeViewModel>
      {
          ...
      }
      
    5. 对于所有子视图(从主视图打开),确保将MvxSidebarPresentationAttribute 设置为Panel 属性设置为CenterHintType 设置为PushPanel 并取决于您是否需要要在子页面上显示菜单按钮,请将 ShowPanel 设置为 truefalse,如下所示:

      [MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.PushPanel, true)]
      public class ChildView : MvxViewController<ChildViewModel>
      {
          ...
      }
      
    6. 最后一步是为菜单中的所有其他按钮设置视图控制器。这些可以简单地用MvxModalPresentationAttribute 属性修饰以将它们作为对话框打开(可以找到详细文档here)。示例可能如下所示:

      [MvxModalPresentation(ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen, ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve)]
      public partial class ModalView : MvxViewController<ModalViewModel>
      {
          ...
      }
      

    要打开不同的视图,您可以使用 MvvmCross 中的新导航服务。为此,只需允许 MvvmCross IoC 容器将实例注入到您的视图模型构造函数中(更多详细信息可以在 here 找到):

    public class HomeViewModel : MvxViewModel
    {
        private readonly IMvxNavigationService _navigationService;
    
        public HomeViewModel(IMvxNavigationService navigationService)
        {
            _navigationService = navigationService ?? throw new ArgumentNullException(nameof(navigationService));
        }
    }
    

    编辑 1: 为了能够将图标显示为菜单按钮,您需要在构成菜单的视图控制器上实现IMvxSidebarMenu 接口(参见步骤 3)。通过实现此接口,您可以覆盖菜单的默认行为,示例可以在 here 找到(它是演示 MvvmCross XamarinSidebar 应用程序的一部分)。

    编辑 2: 我错误地建议您可以在推送到导航堆栈的子视图上显示菜单(或其图标)按钮。情况并非如此,被压入堆栈的子视图不会显示菜单按钮。在这些情况下,ShowPanel 属性将被完全忽略。

    编辑 3: 有一种方法可以完全实现这种模式。我们可以自定义堆栈导航 UI,这样我们就可以模仿 Android 工具栏之类的东西。这种方法有效,它基本上要求我们隐藏导航栏并创建我们的自定义工具栏,其中包含汉堡菜单、后退按钮和其他按钮,并将其放在子视图的上部。以下是关闭和返回按钮所需的代码:

    public override void ViewDidLoad()
            {
                base.ViewDidLoad();
                NavigationController.NavigationBarHidden = true;
    
                btnClose.TouchUpInside += (object sender, EventArgs e) =>
                {
                    NavigationController.NavigationBarHidden = false;
                    NavigationController.PopViewController(false);
                };
    
                btnShowMenu.TouchUpInside += (object sender, EventArgs e) =>
                {
                    var sideMenu = Mvx.Resolve<IMvxSidebarViewController>();
                    sideMenu?.Open(MvxPanelEnum.Left);
                };
            }
    

    【讨论】:

    • 我几乎都是通过使用您的说明修改 Marcs 示例项目来实现的,但仍然存在两个问题。 1.我没有菜单按钮(汉堡包),只有“菜单”这个词。 2. 当子页面打开时,它有导航栏(我可以使用 NavigationController.NavigationBarHidden = false 隐藏它),但是无论我设置 showpanel=true 还是 showpanel=false,当子页面处于活动状态时我都看不到汉堡菜单) .你可以在这里找到我的测试项目:1drv.ms/u/s!ArCs7A3yxQw8pTdWUPhgF0EUTu-L
    • 我已更新我的原始帖子以回答您的其他问题。不幸的是,我说您可以在子视图上显示菜单图标,这有点误导了您。
    • 感谢您的帮助。您是说我们无法创建在 eBay 或 Amazon 等应用程序中显示的导航,其中导航到主菜单会启动某种堆栈导航,同时保留菜单面板并允许用户随时跳转到主屏幕(对话框除外) .有没有其他方法可以帮助我完成这种导航模式。
    • 当然可以这样做,但是我们还没有这样实现。在我们的实现中,当您在导航堆栈上推送子视图时,我们会显示一个后退按钮(根据 Apple 人机界面指南:“使用导航栏遍历数据层次结构。导航栏的标题可以显示层次结构中的当前位置, 后退按钮可以轻松返回到上一个位置。有关具体指导,请参阅导航栏。”,另请参阅here)。
    • @MauritsvanBeusekom 很好的解释,尝试按照你的建议做,但收到警告 - 你能看看这里 - stackoverflow.com/q/45082154/2012219 和建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多