在 Xamarin.Forms 快速入门中,生成了 Phoneword 应用程序。 本文回顾生成的内容,以深入了解有关 Xamarin.Forms 应用程序工作原理的基础知识。
探讨了以下主题:
Visual Studio 是 Microsoft 提供的强大 IDE。 它采用完全集成的可视化设计器、包含重构工具的文本编辑器、程序集浏览器、源代码集成等。 本文重点介绍如何通过 Xamarin 插件使用 Visual Studio 的一些基本功能。
Visual Studio 将代码组织为解决方案和项目。 解决方案是可以容纳一个或多个项目的容器。 项目可以是应用程序、支持库、测试应用程序等。 Phoneword 应用程序包含 1 个内附 6 个项目的解决方案,如以下屏幕截图所示。
这些项目如下:
以下屏幕截图显示 Visual Studio 中 Phoneword PCL 项目的内容:
项目包含 2 个文件夹:
项目还包括多个文件:
App
类的 XAML 标记,该类定义应用程序的资源字典。App
类的代码隐藏,该类负责实例化应用程序在每个平台上将显示的首页,并处理应用程序生命周期事件。IDialer
接口,该接口指定 Dial
方法必须由任何实现类提供。MainPage
类的 XAML 标记,该类定义应用程序启动时所显示页的 UI。MainPage
类的代码隐藏,该类包含用户与页面交互时执行的业务逻辑。有关 Xamarin.iOS 应用程序剖析的详细信息,请参阅 Xamarin.iOS 应用程序剖析。 有关 Xamarin.Android 应用程序剖析的详细信息,请参阅 Xamarin Android 应用程序剖析。
Xamarin.Forms 应用程序采用与传统跨平台应用程序相同的构建方式。 共享代码通常位于可移植类库 (PCL) 中,平台特定应用程序使用此共享代码。 下图概要演示了 Phoneword 应用程序的这种关系:
有关 PCL的详细信息,请参阅可移植类库简介。
若要最大限度重用启动代码,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();
}
...
}
}
此代码将 App
类的 MainPage
属性设置为 MainPage
类的一个新实例。 此外,XamlCompilation
属性可打开 XAML 编译器,以使 XAML 直接编译为中间语言。 有关详细信息,请参阅 XAML 编译。
若要在 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 框架。 这会导致在调用将根视图控制器设置为LoadApplication
方法之前,将特定于 iOS 的 Xamarin.Forms 实现加载到应用程序。
若要在 Android 中启动 Xamarin.Forms 初始页面,Phoneword.Droid 项目应包括使用 MainLauncher
属性创建活动的代码,以及继承自 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.Forms 框架。 这会导致在加载 Xamarin.Forms 应用程序之前,将特定于 Android 的 Xamarin.Forms 实现加载到应用程序。
在通用 Windows 平台 (UWP) 应用程序中,可从 App
类调用初始化 Xamarin.Forms 框架的 Init
方法:
Xamarin.Forms.Forms.Init (e);
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
...
}
这会将特定于 UWP 的 Xamarin.Forms 实现加载到应用程序。 可通过 MainPage
类启动 Xamarin.Forms 初始页面,如以下代码示例所示:
namespace Phoneword.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
this.LoadApplication(new Phoneword.App());
}
}
}
可通过 LoadApplication
方法加载 Xamarin.Forms 应用程序。
可使用 4 个主要控件组创建 Xamarin.Forms 应用程序的用户界面。
ContentPage
类显示单个屏幕。 有关页面的详细信息,请参阅 Xamarin.Forms 页面。StackLayout
类以水平堆叠方式排列控件。 有关布局的详细信息,请参阅 Xamarin.Forms 布局。Label
、Entry
和 Button
控件。 有关视图的详细信息,请参阅 Xamarin.Forms 视图。在运行时,每个控件都会映射到其本身的本机等效项(即呈现的内容)。
在任一平台运行 Phoneword 应用程序时,此应用会显示对应于 Xamarin.Forms 中 Page
的单一屏幕。 Page
在 Android 中表示为一个 ViewGroup,在 iOS 中表示为视图控制器,在 Windows 通用平台中则表示为一个页面。 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
本身未进行填充,但进行了扩展。 StackLayout
控件包含 1 个用于在页面上显示文本的 Label
控件、1 个用于接收文本用户输入的 Entry
控件和 2 个用于在响应触摸事件时执行代码的 Button
控件。
有关 Xamarin.Forms 中 XAML 的详细信息,请参阅 Xamarin.Forms XAML 基础知识。
XAML 中定义的对象可触发在隐藏文件中处理的事件。 以下代码示例演示了 MainPage
类的代码隐藏中的 OnTranslate
方法,该类在响应 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
方法将 phoneword 转换为其相应的电话号码,并在响应时设置调用按钮上的属性。 XAML 类的代码隐藏文件可使用为其分配的、具有 x:Name
属性的名称访问 XAML 中定义的对象。 分配给此属性的值与 C# 变量的规则相同,因为该值必须以字母或下划线开头,且不包含嵌入的空格。
对 OnTranslate
方法的切换按钮布线会在 MainPage
类的 XAML 标记中出现:
<Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />
用于 Xamarin.Forms 的 Phoneword 应用程序引入了多个本文未提及的概念。 这些概念包括:
启用和禁用按钮。 通过更改 Button
的 IsEnabled
属性,可将其打开或关闭。 例如,以下代码示例禁用 callButton
:
callButton.IsEnabled = false;
显示警报对话框。 用户按呼叫按钮时,Phoneword 应用程序会显示“警报”对话框,其中包含发出或取消呼叫的选项。DisplayAlert
方法用于创建该对话框,如以下代码示例所示:
await this.DisplayAlert (
"Dial a Number",
"Would you like to call " + translatedNumber + "?",
"Yes",
"No");
通过 DependencyService
类访问本机功能。 Phoneword 应用程序使用 DependencyService
类将 IDialer
接口解析到特定于平台的电话拨号实现中,如以下 Phoneword 项目中的代码示例所示:
async void OnCall (object sender, EventArgs e)
{
...
var dialer = DependencyService.Get<IDialer> ();
...
}
有关 DependencyService
类的详细信息,请参阅通过 DependencyService 访问本机功能。
通过 URL 发出电话呼叫。 Phoneword 应用程序使用 OpenURL
启动系统电话应用。 URL 包含 tel:
前缀,后跟要呼叫的电话号码,如以下 iOS 项目中的代码示例所示:
return UIApplication.SharedApplication.OpenUrl (new NSUrl ("tel:" + number));
调整平台布局。 使用 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>
有关平台调整的详细信息,请参阅设备类。
Xamarin Studio 和 Visual Studio 均提供许多用于测试和部署应用程序的选项。 调试应用程序是应用程序开发生命周期的普遍一环,有助于诊断代码问题。 有关详细信息,请参阅设置断点、逐步执行代码和日志窗口的输出信息。
模拟器是开始部署和测试应用程序的有利位置,其提供用于测试应用程序的有用功能。 但是,用户不会在模拟器中使用最终应用程序,因此应尽早并经常在实际设备上测试应用程序。 有关 iOS 设备预配的详细信息,请参阅设备预配。 有关 Android 设备预配的详细信息,请参阅设置设备进行开发。
本文介绍了使用 Xamarin.Forms 开发应用程序的基础知识。 涵盖的主题包括:Xamarin.Forms 应用程序剖析、体系结构和应用程序基础知识以及用户界面。
在本指南的下一部分,将介绍如何扩展应用程序以包含多个屏幕,从而探索更高级的 Xamarin.Forms 体系结构和概念。