做XamarinForms快一年了,最近趁着项目不是很紧,有点空闲的时间,研究了一下MvvmCross这个框架,感觉挺高大上的。一边研究一下写点入门的东西吧,大部分的东西github都有。
1添加Package
主要添加了四个MvvmCross相关的Package,.Droid 还有 .iOS 中引入相同的Package。
2初始化的文件
对于这个MvvmCross应用来说,重要的两个类如下:
(1) App:这个类是在Core项目中,为整个核心的业务逻辑跟viewmodels提供初始化入口
(2)Setup:Android跟iOS项目的MvvmCross系统的启动程序
因为创建Demo工程的时候选择了“User XAML for user interface files”,所以App文件也是xaml的,为了避免后面的麻烦,这里需要删除,重新添加一个App.cs文件,代码如下:
using MvvmCross.Platform.IoC; using MvvmCross.Core.ViewModels; namespace MvvmCrossDemo { public class App : MvxApplication { public override void Initialize() { CreatableTypes().EndingWith("Service").AsInterfaces().RegisterAsLazySingleton(); RegisterAppStart<ViewModels.FirstViewModel>(); } } }
PLC中的初始化就算是完成了,CreatableTypes:找到所有可以创建的Type,有公共构造函数以及不是抽象的;AsInterfaces:找到interface的实现;RegisterAsLazySingleton:来一个请求实例化一下接口的实现,相当于懒加载,接下来的请求返回先前的实现,就是单例。
接下来就是Droid跟iOS中的初始化了,先来iOS的,首先是先写一个Setup文件,这个需要在AppDelegate中用到,代码如下:
using System; using UIKit; using Xamarin.Forms; using MvvmCross.Forms.Presenter.Core; using MvvmCross.Forms.Presenter.iOS; using MvvmCross.Platform.Platform; using MvvmCross.Core.ViewModels; using MvvmCross.iOS.Platform; using MvvmCross.iOS.Views.Presenters; namespace MvvmCrossDemo.iOS { public class Setup :MvxIosSetup { public Setup (IMvxApplicationDelegate applicationDelegate, UIWindow window):base(applicationDelegate,window) { } protected override IMvxApplication CreateApp() { return new App(); }
//非必须的 protected override IMvxIosViewPresenter CreatePresenter() { Forms.Init(); var xamarinFormsApp = new MvxFormsApp(); return new MvxFormsIosPagePresenter(Window, xamarinFormsApp); } } }
接下来是修改AppDelegate.cs,整个的加载过程跟之前的模式不同了,代码如下:
using System; using System.Collections.Generic; using System.Linq; using Foundation; using UIKit; using MvvmCross.iOS.Platform; using MvvmCross.Core.ViewModels; using MvvmCross.Platform; namespace MvvmCrossDemo.iOS { [Register("AppDelegate")] public partial class AppDelegate : MvxApplicationDelegate { UIWindow _window; public override bool FinishedLaunching(UIApplication app, NSDictionary options) { _window = new UIWindow(UIScreen.MainScreen.Bounds); var setup = new Setup(this, _window); setup.Initialize(); var startup = Mvx.Resolve<IMvxAppStart>(); startup.Start(); _window.MakeKeyAndVisible(); return true; } } }
这样下来,iOS应该就可以编译通过了。接下来介绍下Droid,同样,也是要先建立一个Setup.cs文件,如下:
using System; using MvvmCross.Platform; using MvvmCross.Platform.Platform; using MvvmCross.Core.ViewModels; using MvvmCross.Core.Views; using MvvmCross.Droid.Platform; using MvvmCross.Droid.Views; using MvvmCross.Forms.Presenter.Droid; using Android.Content; namespace MvvmCrossDemo.Droid { public class Setup:MvxAndroidSetup { public Setup(Context applicationContent):base(applicationContent) { } protected override IMvxApplication CreateApp() { return new App(); }
//非必须 protected override IMvxAndroidViewPresenter CreateViewPresenter() { var presenter = new MvxFormsDroidPagePresenter(); Mvx.RegisterSingleton<IMvxViewPresenter>(presenter); return presenter; } } }
另一个必须的文件,像是Android的Application,而创建工程时候生成的MainActivity.cs可以删除了,新添加的文件代码如下:
using System; using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Android.Content.PM; using Xamarin.Forms.Platform.Android; using Xamarin.Forms; using MvvmCross.Forms.Presenter.Core; using MvvmCross.Forms.Presenter.Droid; using MvvmCross.Platform; using MvvmCross.Core.ViewModels; using MvvmCross.Core.Views; namespace MvvmCrossDemo.Droid { [Activity(Label="MvxApplicationActivity",ScreenOrientation=ScreenOrientation.Portrait)] public class MvxFormsApplicationActivity:FormsApplicationActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Forms.Init(this, savedInstanceState); var mvxFormsApp = new MvxFormsApp(); LoadApplication(mvxFormsApp); var presenter = Mvx.Resolve<IMvxViewPresenter>() as MvxFormsDroidPagePresenter; presenter.MvxFormsApp = mvxFormsApp; Mvx.Resolve<IMvxAppStart>().Start(); } } }
另外,创建一个SplashScreen页面,设置 MainLauncher = true,代码略。
3.说一下PCL部分,mvvm,so,文档结构如下:
下面说一下ViewModel部分,首先要继承 MvxViewModel,Command要用MvxCommand,按照约定俗成,ViewModel的构造函数用来依赖注入,而页面跳转中的数据传递,要靠Init()来接收参数。
备注一下:在添加package的时候,搜索mvvmcross starterpack 快速引入Mvvm Cross框架,Android以及iOS工程同样的引入该starterpack,然后稍微做一下改动,一分钟引入该框架。