Xamarin.Android之MvvmCross

歡迎你們加入如下開源社區android

Xamarin-Cn:https://github.com/Xamarin-Cngit

Mvvmcross-Cn:https://github.com/Mvvmcross-Cn github

(另外微信訂閱號 Xamarin 全部者@善友兄也給予了運營權限,後面將開始陸續運營起來,給你們推送相關的文章)微信

 

簡介

相信作了開發有必定經驗的人都知道IOC的存在,而Xamarin.Android中尚未IOC的存在。特別是在Xamarin.Android下,若是僅僅只是顯示簡單的數據,就須要經過不少的FindViewById來查找組件,而且還要負責呈現,今天咱們將經過學習MVVMCross組件來簡化這些操做,達到PCL部分的最大化,下面咱們以一個官方的DEMO來學習。app

 

題外話:ide

因爲公司的發展須要,須要招聘Xamarin方面的人才,若是你對Xamarin感興趣的能夠直接聯繫樓主,如今咱們要召集8我的進行這方面的培訓,因此只要有C#基礎,而且有很強的興趣均可以來。而且在產品完成後咱們將會把開發的經驗都撰寫成博客發表,造福整個Xamarin(Q+976691141)。 函數

 

PCL部分

 

基礎準備

首先咱們須要新建一個名爲「TipCalc.Core」的「類庫(可移植)」的項目,而且咱們須要按照下圖選擇對應的平臺:學習

 

若是你的平臺沒有紅色框住的部分也沒有問題的,由於當前主流的PCL的方案是Profile259,若是你要查看你新建的類庫是否是259能夠查看項目的csproj文件,就是{項目名}.csproj,用記事本打開,而後定位到這個位置就能夠看到了:spa

 

警告:code

若是上面的PCL部分你按照個人選擇以後,肯定按鈕是禁用的,就須要跟着下面的教程來解決這個問題,首先咱們須要打開下面這個文件夾:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile78\SupportedFrameworks

將該文件夾中的如下文件複製:

若是不存在「Xamarin.iOS.Unified.xml」也沒有關係,以後咱們打開下面這個文件夾:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile259\SupportedFrameworks

 

將上面的文件複製到其中,而後重啓VS就能夠解決問題了。

 

項目搭建

 

刪除Class1.cs文件

咱們並不須要使用該文件

 

安裝MvvmCross

咱們打開「程序包管理器控制檯」輸入如下指令後回車:

Install-Package MvvmCross.HotTuna.MvvmCrossLibraries

 

 

添加Tip Calculation 服務

建立一個名爲「Services」的文件夾,並在該文件夾中新建一個名爲「ICalculation」的接口,具體的內容代碼以下所示:

1 namespace TipCalc.Core.Services
2 {
3     public interface ICalculation
4     {
5         double TipAmount(double subTotal, int generosity);
6     }
7 }

 

 

並在該文件夾中新建一個Calculation類實現上面的接口,具體代碼以下:

 1 namespace TipCalc.Core.Services
 2 {
 3     public class Calculation : ICalculation
 4     {
 5         public double TipAmount(double subTotal, int generosity)
 6         {
 7             return subTotal * ((double)generosity)/100.0;
 8         }
 9     }
10 }

以上部分在實際項目中咱們能夠認爲是應用服務層。

 

添加視圖模型

視圖模型將會鏈接最終的界面與上面的服務層,而爲了達到這些效果,咱們的視圖模型必須繼承自MvxViewModel。下面咱們先新建一個ViewModels文件夾並新建一個TipViewModel類,具體的代碼以下所示:

 1 namespace TipCalc.Core.ViewModels
 2 {
 3     public class TipViewModel : MvxViewModel
 4     {
 5         private readonly ICalculation _calculation;
 6         public TipViewModel(ICalculation calculation)
 7         {
 8             _calculation = calculation;
 9         }
10 
11         public override void Start()
12         {
13             _subTotal = 100;
14             _generosity = 10;
15             Recalcuate();
16             base.Start();
17         }
18 
19         private double _subTotal;
20 
21         public double SubTotal
22         {
23             get { return _subTotal; }
24             set { _subTotal = value; RaisePropertyChanged(() => SubTotal); Recalcuate(); }
25         }
26 
27         private int _generosity;
28 
29         public int Generosity
30         {
31             get { return _generosity; }
32             set { _generosity = value; RaisePropertyChanged(() => Generosity); Recalcuate(); }
33         }
34 
35         private double _tip;
36 
37         public double Tip
38         {
39             get { return _tip; }
40             set { _tip = value; RaisePropertyChanged(() => Tip);}
41         }
42 
43         private void Recalcuate()
44         {
45             Tip = _calculation.TipAmount(SubTotal, Generosity);
46         }
47     }
48 }

經過上面的代碼咱們能夠看到,視圖模型的構造函數要求傳入一個實現了ICalculation接口的參數,而這個過程將會有IOC幫咱們完成。剩下的咱們能夠看到咱們重寫了Start方法用來給視圖模型中的值賦初始值,而且在每一個值改變的同時還調用了Recalcuate方法來從新計算。

 

OK,完成這些以後,咱們還須要一個啓動項對依賴注入進行配置,而且指定初始顯示的視圖模型,咱們直接在項目根目錄下新建一個App類,而且該類須要繼承自MvxApplication類,並在構造函數中寫入如下代碼:

 1 namespace TipCalc.Core
 2 {
 3     public class App : MvxApplication
 4     {
 5         public App()
 6         {
 7             Mvx.RegisterType<ICalculation,Calculation>();
 8             Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<TipViewModel>());
 9         }
10     }
11 }

其中咱們能夠看到咱們經過Mvx.RegisterType對IOC進行了配置,這樣IOC纔可以知道在須要ICalculation接口的時候實例化哪一個類,而下一行的代碼則是指定初始的視圖模型,也就是首頁,完成上面這些配置後咱們的PCL部分完成了,能夠通用於Android和IOS。

 

Android UI呈現

首先咱們建立一個「Blank App(Android)」項目,項目名爲「TipCalc.UI.Droid」。並將項目默認生成的MainActivity.cs文件和Resources/Layout文件夾下的Main.axml刪除並添加TipCalc.Core.csproj引用。

 

安裝MvvmCross

跟PCL部分同樣,咱們還須要安裝對應的類庫:

Install-Package MvvmCross.HotTuna.MvvmCrossLibraries

 

 

添加MvvmCross Android綁定資源

該部分是爲了咱們可以在界面中使用bind屬性,因此咱們須要在Resources/Values文件夾下新建一個xml資源,名字能夠爲「MvxBind」,對應的內容以下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3   <declare-styleable name="MvxBinding">
 4     <attr name="MvxBind" format="string"/>
 5     <attr name="MvxLang" format="string"/>
 6   </declare-styleable>
 7   <declare-styleable name="MvxListView">
 8     <attr name="MvxItemTemplate" format="string"/>
 9     <attr name="MvxDropDownItemTemplate" format="string"/>
10   </declare-styleable>
11   <item type="id" name="MvxBindingTagUnique"/>
12   <declare-styleable name="MvxImageView">
13     <attr name="MvxSource" format="string"/>
14   </declare-styleable>
15 </resources>

 

 

添加啓動類

雖然PCL中有啓動項了,可是咱們須要在特定中進行註冊,因此咱們還須要新建一個Setup類,而且該類的主要內容以下:

 1 namespace TipCalc.UI.Droid
 2 {
 3     public class Setup : MvxAndroidSetup
 4     {
 5         public Setup(Context applicationContext)
 6             : base(applicationContext)
 7         {
 8         }
 9 
10         protected override IMvxApplication CreateApp()
11         {
12             return new App();
13         }
14     }
15 }

主要做用就是將App實例化並返回,以便在特定平臺中進行初始化。

 

添加視圖

咱們須要在Resources/Layout文件夾下新建一個視圖名爲View_Tip.axml,而且其中的內容以下所示:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:local="http://schemas.android.com/apk/res/TipCalc.UI.Droid"
 4     android:orientation="vertical"
 5     android:layout_width="fill_parent"
 6     android:layout_height="fill_parent">
 7     <TextView
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content"
10         android:text="SubTotal" />
11     <EditText
12         android:layout_width="fill_parent"
13         android:layout_height="wrap_content"
14         local:MvxBind="Text SubTotal" />
15     <TextView
16         android:layout_width="fill_parent"
17         android:layout_height="wrap_content"
18         android:text="Generosity" />
19     <SeekBar
20         android:layout_width="fill_parent"
21         android:layout_height="wrap_content"
22         android:max="40"
23         local:MvxBind="Progress Generosity" />
24     <View
25         android:layout_width="fill_parent"
26         android:layout_height="1dp"
27         android:background="#ffff00" />
28     <TextView
29         android:layout_width="fill_parent"
30         android:layout_height="wrap_content"
31         android:text="Tip to leave" />
32     <TextView
33         android:layout_width="fill_parent"
34         android:layout_height="wrap_content"
35         local:MvxBind="Text Tip" />
36 </LinearLayout>

經過其中的內容咱們能夠看到,其中多了一個MvxBind屬性,經過這個屬性咱們能夠直接將控件的屬性直接與ViewModel中對應的屬性直接關聯起來,這樣咱們能夠省去與控件交互的部分,可是咱們仍是須要Activity來將界面與咱們的ViewModel進行關聯。

 

添加視圖類

咱們直接新建一個名爲TipCalcView的活動,而後將其繼承的類改爲MvxActivity,具體的代碼以下:

 1 namespace TipCalc.UI.Droid.Views
 2 {
 3     [Activity(Label = "Tip", MainLauncher = true)]
 4     public class TipView : MvxActivity
 5     {
 6         public new TipViewModel ViewModel
 7         {
 8             get { return (TipViewModel) base.ViewModel; }
 9             set { base.ViewModel = value; }
10         }
11 
12         protected override void OnViewModelSet()
13         {
14             base.OnViewModelSet();
15             SetContentView(Resource.Layout.View_Tip);
16         }
17     }
18 }

完成這些以後,直接運行,咱們能夠看到調整進度條的同時,Tip to leave的值會跟着動,徹底是實時的。

 

固然原生的方式與MvvmCross的方式是能夠直接並存的。

相關文章
相關標籤/搜索