我正在与嵌套片段斗争。我有一个活动,使用抽屉换出另一个片段的主要内容。其中一些第二个片段是主 - 详细视图,其中详细视图采用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中处理每个可能的孙子片段,但这似乎对我来说是漏洞。