嵌套片段和自定义演示者

时间:2014-07-22 18:41:16

标签: mvvmcross

我正在与嵌套片段斗争。我有一个活动,使用抽屉换出另一个片段的主要内容。其中一些第二个片段是主 - 详细视图,其中详细视图采用DetailsViewModel。

public class CustomPresenter : MvxAndroidViewPresenter, ICustomPresenter
{
    // map between view-model and fragment host which creates and shows the view based on the view-model type
    private readonly Dictionary<Type, IFragmentHost> _dictionary = new Dictionary<Type, IFragmentHost>();

    public override void Show(MvxViewModelRequest request)
    {
        IFragmentHost host;
        if (this.TryGetHost(request.ViewModelType, out host))
        {
            if (host.Show(request))
                return;
        }
        base.Show(request);
    }

    public override void Close(IMvxViewModel viewModel)
    {
        IFragmentHost host;
        if (this.TryGetHost(viewModel.GetType(), out host))
        {
            host.Close(viewModel);
            return;
        }

        base.Close(viewModel);
    }

    public void Register(Type viewModelType, IFragmentHost host)
    {
        this._dictionary[viewModelType] = host;
    }

    private bool TryGetHost(Type viewModelType, out IFragmentHost host)
    {
        if (this._dictionary.TryGetValue(viewModelType, out host))
            return true;

        host = null;
        return false;
    }
}

在我的活动中:

    private void RegisterNavigationViewModels()
    {
        var presenter = Mvx.GetSingleton<ICustomPresenter>();

        presenter.Register(typeof(MapFragViewModel), this);
        presenter.Register(typeof(PersonnelViewModel), this);
    }

    public bool Show(MvxViewModelRequest request)
    {
        // Handle drawer navigation

        try
        {
            Fragment contentFragment = this.FragmentManager.FindFragmentById(Resource.Id.content_frame);

            MvxFragment fragment;
            var section = this.OperationsViewModel.GetSectionForViewModel(request.ViewModelType);

            switch (section)
            {
                case OperationsViewModel.Section.Map:
                    if (contentFragment is MapFragment)
                        return true;

                    fragment = new MapFragment();
                    break;
                case OperationsViewModel.Section.Personnel:
                    if (contentFragment is OperationalPersonnel)
                        return true;

                    fragment = new OperationalPersonnel();
                    break;
                default:
                    Mvx.TaggedError("Operations Show", "Invalid Show request for {0}", request.ViewModelType.ToString());
                    return false;
            }

            var loaderService = Mvx.Resolve<IMvxViewModelLoader>();
            var viewModel = loaderService.LoadViewModel(request, null /* saved state */);

            fragment.ViewModel = viewModel;

            // HACK
            if (section == OperationsViewModel.Section.Map)
                fragment.ViewModel = this.OperationsViewModel.MapFragViewModel;

            FragmentManager.BeginTransaction().Replace(Resource.Id.content_frame, fragment/*, fragmentView.GetType().ToString()*/).Commit();
            this._drawerList.SetItemChecked(this.OperationsViewModel.NavigationItems.FindIndex(m => m.Id == (int)section), true);

            return true;
        }
        finally
        {
            this._drawerLayout.CloseDrawer(this._drawerList);
        }
    }

如您所见,Show()处理导航窗口。我想在子片段OperationalPersonnel中可能有一种方法可以在OnAttach中注册父活动和演示者,并在OnDetach中取消注册并以某种方式控制那里的映射?但是我仍然不知道如何处理Show()...也许将控制委托给子片段?或者,我想我可以在Show中处理每个可能的孙子片段,但这似乎对我来说是漏洞。

0 个答案:

没有答案