MvvmCross app-wide NavigationDrawer实现xamarin.droid

时间:2014-05-01 06:16:56

标签: android-fragments xamarin.android xamarin mvvmcross

我已经玩了一段时间了,我只是想知道添加应用程序范围的NavigationDrawer的最佳方法。

  1. 从我可以收集的内容来看,最好的方法是实现v4小部件系统并将每个视图作为片段放入并将其放入' HomeView' (这只是包含NavigationDrawer的主视图和以编程方式覆盖的片段)。这种方法似乎在理论上是最干净的,但后来我失去了使用MvvmCross所带来的所有细节,似乎使用它毫无意义。我的意思是,我将失去在viewmodel上使用ICommand绑定来从片段内导航到另一个子页面/片段。 (除非我错了?)
  2. 我想的另一个选择就是有效地拥有一个'主人'基本视图,我的所有视图都从哪个视图继承了自定义NavigationDrawer并不使用Fragments。但是找到这种设置的例子似乎是不可能的,而且我对Xamarin / MvvmCross来说还是一个新手来尝试这种类型的结构。
  3. 有没有人对此最佳做法有任何建议或想法?理想情况下,我想要选项1,但我希望在ViewModel中保留和维护ICommand绑定,以实现跨平台兼容性。

1 个答案:

答案 0 :(得分:1)

我最终选择了选项1,使用http://motzcod.es/post/60427389481/effective-navigation-in-xamarin-android-part-1作为基准参考点。

我现在有一个主视图(HomeView),而且每个其他页面现在都是一个被放入content_frame片段的片段。

我的所有页面都继承自具有GoToView方法的BaseFrag。这确实意味着我在视图模型中丢失了跨平台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();
        }
    }

我还将尝试重新审视必须传递视图模型并查看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);
        }
    }

但是现在这个问题对我有用,直到我有更多的时间来投资抽象它。