选择

1

目标MvvmCross,机器人选择

目的:一个屏幕(视图模型/视图),其中,用户可以选择的动物组(两栖类,鸟类,鱼类,无脊椎动物,哺乳动物,爬行动物)。当一个组被选中时,Fragment Views将显示该动物组的信息。每个动物组的领域和布局不同(例如,鱼没有翅膀)。 虽然对于这个问题,我选择了动物组(这是非常静态的),要列表动物群体是灵活的。

简化的应用程序结构:

  • MyApp.Core
    • 的ViewModels
    • MainViewModel
    • IAnimalGroupViewModel
    • AmphibiansViewModel
    • BirdsBViewModel
    • FishViewModel
  • MyApp.Droid
    • 布局
      • 的MainView
      • AmphibiansFragment
      • BirdsFragment
      • FishFragment
    • 查看
      • 的MainView
      • AmphibiansFragment
      • BirdsFragment
      • FishFragment

的MainView.axml布局文件将包含(为一个占位符)所显示的动物组的片段。

在WPF或WP8应用程序中,我可以使用ContentPresenter和样式自动显示选定的ViewModel及其视图。

我该如何在Droid中实现类似的功能?

我可以在MainView.cs中使用Switch/Case来根据所选ViewGroup的类型设置Fragment。但是这意味着我每次添加新视图时都必须修改MainView。

任何建议/想法?

+0

已经回答了一次......但在我的脑海里有一种替代的基于XML的方法......还没有完全计算出它现在的功能...... – Stuart

回答

1

目前MvvmCross没有以与活动相同的方式为碎片提供任何类型的自动导航机制。然而,在您的使用案例中,如果您想使用导航方法,那么您可以自动构建类似类型的自动查找/导航机制。

要做到这一点,最简单的开发根很可能会使用反射来找到一个查找字典的所有片段

var fragments = from type in this.GetType().Assembly.GetTypes() 
       where typeof(IAnimalGroupView)..sAssignableFrom(type) 
       where type.Name.EndsWith("Fragment") 
       select type; 
var lookup = fragments.ToDictionary(
        x => x.Name.Substring(0, x.Name.Length - "Fragment".Length) 
           + "ViewModel", 
        x => x); 

有了这个地方,那么你可以创建片段在需要的时候 - 例如

  • 假设你通过一个ICommand转换评选活动的视图模型为ShowViewModel<TViewModel>呼叫
  • ,并假设你有一个自定义MVX演示其截获这些ShowViewModel请求,并将它们传递给活动(类似于Fragment sample) - 例如

    public class CustomPresenter 
        : MvxAndroidViewPresenter 
    { 
        // how this gets set/cleared is up to you - possibly from `OnResume`/`OnPause` calls within your activities. 
        public IAnimalHostActivity AnimalHost { get; set; } 
    
        public override void Show(MvxViewModelRequest request) 
        { 
         if (AnimalHost != null && AnimalHost.Show(request)) 
          return; 
    
         base.Show(request); 
        } 
    } 
    
  • 那么你的活动可以用下面的方法实现Show

    if (!lookup.ContainsKey(request.ViewModelType.Name)) 
        return false; 
    
    var fragmentType = lookup[request.ViewModelType.Name]; 
    var fragment = (IMvxFragmentView)Activator.Create(fragmentType); 
    fragment.LoadViewModelFrom(request); 
    
    var t = SupportFragmentManager.BeginTransaction(); 
    t.Replace(Resource.Id.my_selected_fragment_holder, fragment); 
    t.Commit(); 
    return true; 
    

注:

  • ,如果你不使用ShowViewModel这里那么很明显,同样的方法可能调整...但这个答案不得不提出一些...
  • 在一个更大的多页面应用程序中,您可能会希望使这个IAnimalHostActivity机制更加通用,并在多个地方使用它。