有没有一种很好的方法来模拟iOS中的Android Fragment Pattern?

时间:2014-01-18 20:08:31

标签: cross-platform xamarin mvvmcross portable-class-library

我们在我们的应用中使用MvvmCross。在我们的Android应用中,我们使用NavigationDrawer作为菜单。我们加载包含NavigationDrawer和ContentFrame

的HomeView
<android.support.v4.widget.DrawerLayout >

    <!-- The main content view -->
    <FrameLayout android:id="@+id/content_frame" />

    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer" />

</android.support.v4.widget.DrawerLayout>

当触发OnCreate()方法时,我们会根据数据库查询将AudioPlayerFragment加载到content_frame中。在同一个方法中,我们设置了一个监听器,等待用户单击导航抽屉中的一个ListItem。

protected override void OnCreate(Bundle bundle) {
   // do stuff to build the nav drawer
    _topDrawerList = FindViewById<MvxListView>(Resource.Id.left_drawer);
    _topDrawerList.ItemClick += (sender, args) = > SelectItem(args.Position, null);

    if(bundle == null)
        SelectItem(0, null);
}

private void SelectItem(int position, UserViewModel currentUser) {
    SupportFragmentManager.BeginTransaction()...
}

我们的应用程序运行良好,我喜欢HomeView是应用程序的唯一视图。其他一切都是碎片。

在我们的Core库中,我们有一个用于HomeView的ViewModel,我们还为应用程序中的每个Fragment提供了一个ViewModel。同样,这对我们来说也很有效。

  
      
  • PCL   
        
    • 的ViewModels   
          
      • HomeViewModel
      •   
      • AudioPlayerViewModel&lt; - vm for fragment
      •   
      • LoginFragmentViewModel&lt; - vm for fragment
      •   
    •   
  •   
  • Droid.Ui   
        
    • 片段   
          
      • AudioPlayerFragment
      •   
      • LoginFragment
      •   
    •   
    • 观   
          
      • HomeView &lt; - 只是一个容器查看作为应用程序的入口点。其他一切都是碎片...... AudioPlayerFragment是   立即加载。
      •   
    •   
  •   

现在我正在尝试构建一个匹配的iOS应用程序,但我无法弄清楚如何构建它。基本上我喜欢完全相同的行为,其中HomeView是入口点,并且可以包含SlidingPanel位和某些形式的ContentFrame,其他“视图”可以加载到其中。

不幸的是,现在我已经有了这个愚蠢的MenuView来处理,还有一个相应的MenuViewModel ......我真的不想要。

  
      
  • PCL   
        
    • 的ViewModels   
          
      • HomeViewModel
      •   
      • AudioPlayerViewModel&lt; - vm for fragment
      •   
      • LoginFragmentViewModel&lt; - vm for fragment
      •   
    •   
  •   
  • 触摸UI   
        
    • 观   
          
      • AudioPlayerView
      •   
      • HomeView
      •   
      • LoginView
      •   
      • MenuView &lt; - UGLY !!!
      •   
    •   
    • 的ViewModels   
          
      • MenuViewModel &lt; - UGLY !!!
      •   
    •   
  •   

我真的不想为菜单创建自定义View / ViewModel。我正在使用SlidingPanels作为导航抽屉的iOS“版本”,我看到的教程需要一个额外的View / ViewModel作为菜单。

有没有办法做到这一点,并保持与ViewModels的连续性,以便它们都可以在PCL中重用?是否有一种很好的(阅读清洁)方式以类似于Android的方式构建布局结构?

3 个答案:

答案 0 :(得分:2)

已经尝试过提供由便携式代码驱动的统一用户界面。在MvvmCross中,这些特别是由MonoTouch.Dialog类型的用户界面方法驱动。一个这样的尝试/实验被称为“自动视图” - 您可以在其中看到它:

在此自动视图图层下方,可以在Dialog级别的MvvmCross内轻松共享更多View代码 - 例如见https://github.com/MvvmCross/MvvmCross-Tutorials/tree/master/DialogExamples


然而......据说...迄今为止,大多数自动视图工作仍然专注于提供快速原型而不是完成的应用程序。对于完整的丰富的用户界面,大多数开发人员仍然提供自定义UI。

  

我根本无法绕过iOS UI。与Android相比,我感觉非常陌生。

这并不罕见 - 大多数XAML开发人员比UIKit更快地采用AXML。但是,如果您花一些时间构建一些UIView并使用UIViewController构建一些用户界面(页面),那么我认为您将很快得到UIKit的支持。此外,我相信,一旦你开始看到像UIKit动画这样基于代码的力量,那么你甚至会开始坠入爱河!

答案 1 :(得分:0)

您可以重复使用View模型,但不能重复使用视图。今天,PCL不提供对UI堆栈的访问,因此您无法拥有可移植视图。有关更多详细信息,请查看我们的测试人员撰写的博客文章How to Make Portable Class Libraries Work for You

答案 2 :(得分:0)

我已经确定的方法是使用MvxViewController作为应用程序的基本入口点。

public class HomeView: MvxViewController
{
    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var myEntryFragement = new MyEntryFragment();
        Add(myEntryFragment);
    }
}

然后使用MvxView作为“片段”

public class MyEntryFragment: MvxView // essentially a UIView
{

    private MyEntryViewModel _viewModel;
    public MyEntryFragment()
    {
        // manually construct the _viewModel (or alternatively inject it in the constructor)
        // setup all your UI controls in here
    }

}

然后我根据需要加载和卸载我的“Fragment's”。