Xamarin.Android之MvvmCross


歡迎大家加入以下開源社區

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

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

(另外微信訂閱號 Xamarin 所有者@善友兄也給予了運營權限,后面將開始陸續運營起來,給大家推送相關的文章)

 

簡介

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

 

題外話:

由於公司的發展需要,需要招聘Xamarin方面的人才,如果你對Xamarin感興趣的可以直接聯系樓主,現在我們要召集8個人進行這方面的培訓,所以只要有C#基礎,並且有很強的興趣都可以來。並且在產品完成后我們將會把開發的經驗都撰寫成博客發表,造福整個Xamarin(Q+976691141)。 

 

PCL部分

 

基礎准備

首先我們需要新建一個名為“TipCalc.Core”的“類庫(可移植)”的項目,並且我們需要按照下圖選擇對應的平台:

 

如果你的平台沒有紅色框住的部分也沒有問題的,因為當前主流的PCL的方案是Profile259,如果你要查看你新建的類庫是不是259可以查看項目的csproj文件,就是{項目名}.csproj,用記事本打開,然后定位到這個位置就可以看到了:

 

警告:

如果上面的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的方式是可以直接並存的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM