Xamarin.Forms跨平臺開發入門-第二部分:深刻解析

 

英文原文:

https://developer.xamarin.com/guides/xamarin-forms/getting-started/hello-xamarin-forms/deepdive/#android

 

本文的第一部份內容創建了Phoneword應用。本文是第二部分,回顧了構建的內容以瞭解Xamarin.Forms 應用程序的基本工做原理。ios

 

咱們要討論下面一些問題:程序員

  •  Visual Studio簡介,創建一個新的Xamarin.Forms應用的簡介。
  •  剖析Xamarin.Forms 應用,介紹應用的基本組成部分。
  •  架構和應用程序基礎-每一個平臺是怎麼啓動應用的。
  •  在Xamarin.Forms應用中創建用戶界面。
  •  Phoneword中涉及到的一些額外的概念。
  •  測試和發佈-測試,發佈,生成做品的一些建議。

 

Visual Studio簡介

Visual Studio 是微軟公司的一個強大的IDE。它完整地集成了可視化設計器,文本編輯器,優化重構工具,包管理器,源代碼集成等。本文介紹Xamarin 插件相關的一些基本特徵。架構

 Visual Studio 將代碼組織成解決方案和項目。一個解決方案是一個容器,他能夠容納一個或多個工程。能夠是一個應用工程,支持庫工程,測試工程或其餘工程。Phoneword應用包含一個解決方案,裏面有六個工程,以下圖。app

  

 

這些項目是:框架

Phoneword-本項目是可移植的類庫項目,全部的共享的代碼和共享UI都在裏面。async

Phoneword.Droid - 專門針對Android系統的代碼,和Android應用的入口。編輯器

Phoneword.IOS -專門針對IOS系統的代碼,和IOS應用的入口ide

Phoneword.UWP-專門針對Windows通用平臺(UWP)系統的代碼,和該平臺應用的入口工具

Phoneword.WinPhone- 包含專門針與Windows Phone平臺的代碼,和Windows Phone 8.0 應用的入口。

Phoneword.WinPhone81- 包含專門針與Windows Phone8.1平臺的代碼,和Windows Phone 8.1 應用的入口。

 

Xamarin.Forms應用的剖析。

下圖顯示了Visual Studio中Phoneword PCL工程所包含的內容。

 

 

 

 

這一工程包含兩個文件夾:

Reference - 包含本應用必需的構建和運行時所須要的庫文件。

Properties-包含AssemblyInfo.cs,他是一個.NET庫的元文件,在它裏面放一些關於應用程序的基本信息,這是一個好習慣,關於此文件的更多信息,請參見MSDN 上的AssemblyInfo 類。

 

工程中還包含一些文件:

App.xaml - XAML App 類對應的標記文件,爲應用程序定義了資源字典。

App.xaml.cs - App類的代碼文件,包含了初始化並顯示第一個頁面,還要控制着應用程序生命週期事件。

IDialer.cs - IDialer接口,指明瞭實現類中必須實現的Dial方法。

MainPage.xaml - MainPage 類的XAML標記文件。定義了本應用啓動時的頁面的界面元素(UI)。

MainPage.xaml.cs- MainPagel類的代碼。包含了用戶與界面交互的業務邏輯。

Packages.config-一個XML文件,包含了關於NuGet包的一些信息,用來跟蹤必須的包文件和相應的版本。Xamarin Studio 和Visual Studio均可以配置成自動恢復缺失的Nuget包,當你與其餘程序員共享代碼時,這個文件裏包含的內容有NuGet管理器所控制。

PhoneTranslator.cs - 將電話單詞轉換成電話號碼的業務邏輯,被MainPage.xaml.cs所使用。

 

更多的Xamarin.IOS應用的剖析內容,請參見https://developer.xamarin.com/guides/ios/getting_started/hello,_ios/hello,_ios_deepdive#Anatomy_of_a_Xamarin.iOS_Application/

更多的Xamarin.Android應用的剖析內容,請參見

https://developer.xamarin.com/guides/android/getting_started/hello,android/hello,android_deepdive#Anatomy_of_a_Xamarin.Android_Application/

 

體系結構和應用程序基礎構成

和傳統的跨平臺應用相似,Xamarin.Forms 應用將共享的代碼放入可移植類庫(PCL)內,平臺相關的應用消費這些共享的代碼,下圖展現說明了Phoneword應用的各個部分的關係:

 

 

關於PCL的更多的信息,請參考

https://developer.xamarin.com/guides/cross-platform/application_fundamentals/pcl/introduction_to_portable_class_libraries/

爲了最大化重用啓動代碼,Xamarin.Forms應用有一個單獨的類,叫作App,負責每個平臺的第一個頁面的初始化工做,以下代碼所示:

 

using Xamarin.Forms; using Xamarin.Forms.Xaml;   [assembly: XamlCompilation(XamlCompilationOptions.Compile)] namespace Phoneword {     public partial class App : Application     {         public App()         {             InitializeComponent();             MainPage = new MainPage();         }         ...     } }

 

 

這段代碼將一個一個新的Mainpage實例賦值給App的MainPage屬性。XamlCompilation 屬性打開了XAML 編譯器,以使XAML被編譯成中間語言。更多的關於XAML的內容,請參見

https://developer.xamarin.com/guides/xamarin-forms/xaml/xamlc/

 

在各個平臺上啓動應用

IOS

要在IOS上執行Xamarin.Forms 頁面,Phoneword.IOS工程包含了繼承自FormsApplicationDelegate 的AppDelegate類,以下代碼所示:

 

namespace Phoneword.iOS {     [Register ("AppDelegate")]     public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate     {         public override bool FinishedLaunching (UIApplication app, NSDictionary options)         {             global::Xamarin.Forms.Forms.Init ();             LoadApplication (new App ());             return base.FinishedLaunching (app, options);         }     } }

 

 

經過調用Init方法,FinishedLaunching方法覆蓋了初始化Xamarin.Forms框架的過程。這使得IOS平臺上實現了經過調用LoadApplication方法讓Xamarin.Forms在根View Controller被設置以前被調用。

 

Android

爲了在Android系統上啓動Xamarin.forms頁面,Phoneword.Droid工程包含了建立一個帶有MainLauncher 屬性的 Activity代碼,這個Activity集成自formsApplicationActivity類。以下所示:

 

namespace Phoneword.Droid {     [Activity (Label = "Phoneword.Droid",                Icon = "@drawable/icon",                MainLauncher = true,                ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]     public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity     {         protected override void OnCreate (Bundle bundle)         {             base.OnCreate (bundle);             global::Xamarin.Forms.Forms.Init (this, bundle);             LoadApplication (new App ());         }     } }

 

 

經過調用Init 方法,Oncreate 方法覆蓋了Xamarin.form 的初始化過程,這在Android平臺上實現了在應用程序加載以前加載Xamarin.Forms。

 

通用Windows平臺(UWP)

 

在 通用Windows裏應用裏,初始化Xamarin.Forms 框架的Init方法在App類中啓動。

Xamarin.Forms.Forms.Init (e); if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) {   ... }

 

這使得Xamarin.Forms 在UWP平臺上的實現可以在應用程序中加載進來。初始Xamarin.Forms 頁面被MainPage類加載進來,以下代碼所示。

namespace Phoneword.UWP {     public sealed partial class MainPage     {         public MainPage()         {             this.InitializeComponent();             this.LoadApplication(new Phoneword.App());         }     } }

 

Xamarin.Forms應用程序和LoadApplication方法一塊兒加載。

 

用戶界面(UI)

在Xamarin.Forms應用中,有4個主要控制組用來創建用戶界面。

1.Pages - Xamarin.Forms 頁面展示跨平臺的移動應用屏幕顯示,Phoneword 應用使用了ContentPage類來顯示單個屏幕,更多的關於頁面的內容,請參見 Xamarin.FormsPages (https://developer.xamarin.com/guides/xamarin-forms/controls/pages/)

2.Layouts - Layouts 是一個用來構造視圖邏輯結構的容器。Phoneword使用StackLayout類來安排控件到一個水平的棧上。更多關於Layout的內容,請參見Xamarin.Forms Layouts. (https://developer.xamarin.com/guides/xamarin-forms/controls/layouts/ )。

3.Views - Xamarin.Forms views是顯示在用戶界面上的控件,例如 標籤Labels,按鈕buttons,以及文本輸入框。Phoneword使用了Label,Entry和buttons控件。更多的關於view的內容,參見 Xamarin.Forms Views. (https://developer.xamarin.com/guides/xamarin-forms/controls/views/)

4.Cells - Xamarin.Forms cells 是一些特殊的元素,用來在List裏顯示內容,也描述瞭如何在List裏畫出內容來。Phoneword 沒有用到任何cell,更多關於Cell的內容,請參見 Xamarin.Forms Cells.( https://developer.xamarin.com/guides/xamarin-forms/controls/cells/)

 

運行的時候,每個控件會映射一個本機代碼的元素,而後被渲染出來。

在任意一個平臺上運行Phoneword,每個Xamarin.Forms Page 顯示成一個單一的畫面。所以,一個Page在Android系統上對應ViewGroup,在IOS系統上對應View Controller,在UWP平臺上對應一個Page.Phoneword也實例化一個表明MainPage 類的ContentPage對象,他的XAML代碼以下所示:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"              x:Class="Phoneword.MainPage">              ...     <ContentPage.Content>         <StackLayout VerticalOptions="FillAndExpand"                      HorizontalOptions="FillAndExpand"                      Orientation="Vertical"                      Spacing="15">             <Label Text="Enter a Phoneword:" />             <Entry x:Name="phoneNumberText" Text="1-855-XAMARIN" />             <Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />             <Button x:Name="callButton" Text="Call" IsEnabled="false" Clicked="OnCall" />         </StackLayout>     </ContentPage.Content>
</ContentPage>

 

 

MainPage類使用StackLayout來自動安排控件而不用關心屏幕的大小。每個子元素垂直地一個接一個地排列,StackLayout 在屏幕上所佔用的空間由HorizontalOptions 和VerticalOptions屬性來指定。這種狀況下,FillAndExpand的值指明瞭StackLayout沒有環繞本身的Padding。 StackLayout控件包含一個Label控件用來在頁面上顯示文本。Entry控件用來接受用戶的文本輸入。兩個Button控件用來執行觸摸事件的代碼。

更多關於XAML的內容,請參見Xamarin.Forms XAML 基礎

(https://developer.xamarin.com/guides/xamarin-forms/xaml/xaml-basics/)

 

反應用戶交互

在XAML裏定義的對象能夠引起事件,改事件將被代碼文件所處理。下面的代碼展現了MainPage裏的OnTranslate 方法。它將在Translate按鈕引起Clicked事件時執行。

 

void OnTranslate(object sender, EventArgs e) {     translatedNumber = Core.PhonewordTranslator.ToNumber (phoneNumberText.Text);     if (!string.IsNullOrWhiteSpace (translatedNumber)) {         callButton.IsEnabled = true;         callButton.Text = "Call " + translatedNumber;     } else {         callButton.IsEnabled = false;         callButton.Text = "Call";     } }

 

 

OnTranslate方法將電話單詞翻譯成電話號碼,並設置call 按鈕的屬性。代碼文件能夠用名字訪問XAML裏面使用x:Name定義的對象的屬性。該屬性值的規則與C#變量相同,必須以字母或下劃線開頭,而且不容許有空格存在。

將OnTranslate方法綁定到translate 按鈕上是在MainPage 類的XAML標記裏完成的:

 

<Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />

 

其餘概念

Phoneword 項目中也涉及到了幾個本文沒有說起的概念,包括:

 

l 使按鈕無效/有效。 能夠設置IsEnabled屬性讓按鈕變成有效/無效的狀態,例以下面:

 

callButton.IsEnabled = false;

 

l 顯示警告對話框。 DisplayAlert方法能夠用來建立並顯示對話框。

await this.DisplayAlert (         "Dial a Number",         "Would you like to call " + translatedNumber + "?",         "Yes",         "No");

 

l 使用DependencyService類訪問本地功能,例如,在Phoneword中使用了DependencyService 解決了IDialer接口在不一樣平臺中的撥出電話的實現功能。

 

async void OnCall (object sender, EventArgs e) {     ...     var dialer = DependencyService.Get<IDialer> ();     ... }

 

更多關於DependencyService信息,參見

https://developer.xamarin.com/guides/xamarin-forms/dependency-service/

 

l 使用URL調出撥打電話應用。

URL包含tel:前綴的要撥打的電話號碼,以下代碼:

return UIApplication.SharedApplication.OpenUrl (new NSUrl ("tel:" + number));

 

l 調整平臺的佈局。

Device類可讓開發人員定製應用程序在不一樣平臺上的佈局和功能。例以下面代碼能夠在IOS平臺上使用不一樣的Padding值。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"              ...>      <ContentPage.Padding>         <OnPlatform x:TypeArguments="Thickness"                     iOS="20, 40, 20, 20"                     ... />      </ContentPage.Padding>    ... </ContentPage>

 

更多信息請參見https://developer.xamarin.com/guides/xamarin-forms/platform-features/device/

 

測試和發佈

Xamarin Studio 和Visual Studio 都提供了測試和發佈應用程序的選項。調試應用程序是開發生命週期中共同的部分,用以診斷代碼的問題。更多的內容請參見:

設置斷點 https://developer.xamarin.com/recipes/cross-platform/ide/debugging/set_a_breakpoint/,

單步跟蹤 https://developer.xamarin.com/recipes/cross-platform/ide/debugging/step_through_code/,

日誌輸出 https://developer.xamarin.com/recipes/cross-platform/ide/debugging/output_information_to_log_window/。

 

模擬器是一個進行程序測試和發佈測試的很合適的環境,可是,最終用戶不會將應用程序放在模擬器中使用的。因此開發的程序遲早還得放到真正的設備中運行並進行測試。更多關於IOS設備配置參見:

https://developer.xamarin.com/guides/ios/getting_started/installation/device_provisioning/

更多關於Android 設備配置參見:

https://developer.xamarin.com/guides/android/getting_started/installation/set_up_device_for_development/。

 

總結

本文討論了使用Xamarin.Forms開發的基礎,包括了Xamarin.Forms 應用的分解剖析,架構和應用程序基礎原則,用戶界面等內容。

歡迎繼續關注後續的內容:多屏幕的Phoneword。

相關文章
相關標籤/搜索