Android fragments MvvmCross应用程序范围的NavigationDrawer实现xamarin.droid

Android fragments MvvmCross应用程序范围的NavigationDrawer实现xamarin.droid,android-fragments,xamarin.android,xamarin,mvvmcross,Android Fragments,Xamarin.android,Xamarin,Mvvmcross,我一直在玩这个有一段时间了,我只是想知道最好的方式来加入一个应用程序范围的NavigationDrawer 据我所知,最好的方法是实现v4小部件系统,将每个视图作为一个片段,并将其放入“HomeView”(这只是包含NavigationDrawer和要编程覆盖的片段的主视图)。这种方法在理论上看起来是最干净的,但随后我失去了使用MvvmCross所带来的所有细节,并且似乎使用它来渲染是毫无意义的。我的意思是,我将不再使用viewmodel上的ICommand绑定从片段中导航到另一个子页面/片段。

我一直在玩这个有一段时间了,我只是想知道最好的方式来加入一个应用程序范围的NavigationDrawer

  • 据我所知,最好的方法是实现v4小部件系统,将每个视图作为一个片段,并将其放入“HomeView”(这只是包含NavigationDrawer和要编程覆盖的片段的主视图)。这种方法在理论上看起来是最干净的,但随后我失去了使用MvvmCross所带来的所有细节,并且似乎使用它来渲染是毫无意义的。我的意思是,我将不再使用viewmodel上的ICommand绑定从片段中导航到另一个子页面/片段。(除非我弄错了?)
  • 我想的另一个选择是有效地拥有一个“主”基础视图,我的所有视图都继承自该视图,其中包含一个不使用片段的自定义NavigationDrawer。但是,找到这种设置的示例似乎是不可能的,我对Xamarin/MvvmCross还不太熟悉,所以还没有尝试过这种类型的结构

  • 有没有人对这方面的最佳实践有什么建议或想法?理想情况下,我希望选择选项1,但我希望在ViewModel中保留和维护ICommand绑定,以实现跨平台兼容性。

    我最终选择了选项1,将其用作参考基点

    我现在有一个主视图(HomeView),而每一个页面现在都是一个片段,被放入内容框架片段中

    我的所有页面都继承自BaseFrag,它具有GoToView方法。这确实意味着我在视图模型中丢失了跨平台的ICommand绑定,这是一个遗憾。我以后可能会尝试重新讨论这个问题

    public abstract class BaseFrag : MvxFragment
        {
            protected abstract int ViewId { get; }
    
            public override Android.Views.View OnCreateView(Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Bundle savedInstanceState)
            {
                var ignored = base.OnCreateView(inflater, container, savedInstanceState);
                return this.BindingInflate(ViewId, null);
            }
    
            protected void GoToView<TFrag, TModel>(TFrag fragment, TModel viewModel) where TFrag : MvxFragment where TModel : MvxViewModel
            {
                var activity = (HomeView)Activity;
                fragment.ViewModel = viewModel;
                var trans = activity.SupportFragmentManager.BeginTransaction();
                trans.Replace(Resource.Id.content_frame, fragment);
                trans.AddToBackStack(null);
                trans.Commit();
            }
        }
    
    公共抽象类BaseFrag:MvxFragment
    {
    受保护的抽象int ViewId{get;}
    public override Android.Views.View OnCreateView(Android.Views.LayoutInflater充气机、Android.Views.ViewGroup容器、Bundle savedInstanceState)
    {
    忽略变量=base.OnCreateView(充气机、容器、savedInstanceState);
    返回此值。BindingInflate(视图ID,null);
    }
    受保护的void GoToView(TFrag片段,TModel视图模型),其中TFrag:MvxFragment,其中TModel:MvxViewModel
    {
    var活动=(HomeView)活动;
    fragment.ViewModel=ViewModel;
    var trans=activity.SupportFragmentManager.BeginTransaction();
    trans.Replace(Resource.Id.content\u frame,fragment);
    trans.AddToBackStack(空);
    trans.Commit();
    }
    }
    
    我还将尝试重新访问视图模型,并查看MvvmCross在引擎盖下进行的依赖项注入,以减少此过程的手动性。在我的页面片段中,我只需将click事件绑定到ListViewItem并调用GoToView方法

    public class NowShowingView : BaseFrag
        {
            protected override int ViewId
            {
                get { return Resource.Layout.NowShowingView; }
            }
    
            public override void OnViewCreated(Android.Views.View view, Bundle savedInstanceState)
            {
                var grid = view.FindViewById<MvxGridView>(Resource.Id.now_showing_grid);
                grid.ItemClick = new MvxCommand<RankedMovie>(item => 
                    {
                        var viewModel = new MovieDetailsViewModel(new MovieService());
                        viewModel.Init(item.Title, item.MoviePosterImage, item.Id);
                        GoToView(new MovieDetailsView(), viewModel);
                    });
    
                base.OnViewCreated(view, savedInstanceState);
            }
        }
    
    public类now显示视图:BaseFrag
    {
    受保护的覆盖int ViewId
    {
    获取{return Resource.Layout.NowShowingView;}
    }
    创建视图时公共覆盖无效(Android.Views.View,Bundle savedInstanceState)
    {
    var grid=view.findviewbyd(Resource.Id.now\u显示网格);
    grid.ItemClick=new MvxCommand(item=>
    {
    var viewModel=new MovieDetailsViewModel(new MovieService());
    Init(item.Title、item.MoviePosterImage、item.Id);
    GoToView(新的MovieDetailsView(),viewModel);
    });
    base.OnViewCreated(视图,savedInstanceState);
    }
    }
    

    但这将暂时解决我的问题,直到我有更多的时间将其抽象出来。

    也许有一种方法可以提供一个自定义的MvxAndroidViewPresenter,它在“Show”方法中确定“showViewModelRequest”对象中的类型是Activity类型还是Fragment类型。如果片段然后传递给当前活动的“HandleFragment”方法?我意识到这是一个老问题,但此方法对此非常有用: