做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,然后稍微做一下改動,一分鍾引入該框架。