Xamarin.Forms 深度解析

在 Xamarin.Forms 快速入门中,生成了 Phoneword 应用程序。 本文回顾生成的内容,以深入了解有关 Xamarin.Forms 应用程序工作原理的基础知识。

探讨了以下主题:

  • Visual Studio 简介 - Visual Studio 以及创建新 Xamarin.Forms 应用程序的简介。
  • Xamarin.Forms 应用程序剖析 - Xamarin.Forms 应用程序基本部分的教程。
  • 体系结构和应用程序基础知识 - 每个平台启动应用程序的方式。
  • 用户界面 (UI) - 创建 Xamarin.Forms 的用户界面。
  • Phoneword 中引入的其他概念 - 简单介绍 Phoneword 应用程序使用的其他概念。
  • 测试和部署 - 完成应用程序,并提供有关测试、部署、生成图稿等方面的建议。

Visual Studio 简介

Visual Studio 是 Microsoft 提供的强大 IDE。 它采用完全集成的可视化设计器、包含重构工具的文本编辑器、程序集浏览器、源代码集成等。 本文重点介绍如何通过 Xamarin 插件使用 Visual Studio 的一些基本功能。

Visual Studio 将代码组织为解决方案和项目。 解决方案是可以容纳一个或多个项目的容器。 项目可以是应用程序、支持库、测试应用程序等。 Phoneword 应用程序包含 1 个内附 6 个项目的解决方案,如以下屏幕截图所示。

这些项目如下:

  • Phoneword - 此项目是可移植类库 (PCL) 项目,其中包含所有共享代码和共享 UI。
  • Phoneword.Droid - 此项目包含 Android 特定代码,是 Android 应用程序的入口点。
  • Phoneword.iOS - 此项目包含 iOS 特定代码,是 iOS 应用程序的入口点。
  • Phoneword.UWP - 此项目包含通用 Windows 平台特定代码,是 UWP 应用程序的入口点。
  • Phoneword.WinPhone - 此项目包含 Windows Phone 特定代码,是 Windows Phone 8.0 应用程序的入口点。
  • Phoneword.WinPhone81 - 此项目包含 Windows Phone 8.1 特定代码,是 Windows Phone 8.1 应用程序的入口点。

Xamarin.Forms 应用程序剖析

以下屏幕截图显示 Visual Studio 中 Phoneword PCL 项目的内容:

项目包含 2 个文件夹:

  • 引用 - 包含生成和运行应用程序所需的程序集。
  • 属性 - 包含 .NET 程序集元数据文件 AssemblyInfo.cs。 最好在此文件中填写一些应用程序相关的基本信息。 有关此文件的详细信息,请参阅 MSDN 上的 AssemblyInfo 类。

项目还包括多个文件:

  • App.xaml - App 类的 XAML 标记,该类定义应用程序的资源字典。
  • App.xaml.cs - App 类的代码隐藏,该类负责实例化应用程序在每个平台上将显示的首页,并处理应用程序生命周期事件。
  • IDialer.cs< - IDialer 接口,该接口指定 Dial 方法必须由任何实现类提供。
  • MainPage.xaml - MainPage 类的 XAML 标记,该类定义应用程序启动时所显示页的 UI。
  • MainPage.xaml.cs - MainPage 类的代码隐藏,该类包含用户与页面交互时执行的业务逻辑。
  • packages.config - XML 文件,其中包含项目所使用 NuGet 包的相关信息,以便跟踪所需包及各自的版本。 Xamarin Studio 和 Visual Studio 均可配置为:与其他用户共享源代码时,自动还原任何缺少的 NuGet 包。 此文件的内容由 NuGet 包管理器控制,且不可手动编辑。
  • PhoneTranslator.cs - 负责将电话文字转换为电话号码的业务逻辑,此逻辑从 MainPage.xaml.cs 调用。

有关 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

若要在 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

若要在 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 平台

在通用 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 应用程序的用户界面。

  1. 页面 - Xamarin.Forms 页呈现跨平台移动应用程序屏幕。 Phoneword 应用程序使用 ContentPage 类显示单个屏幕。 有关页面的详细信息,请参阅 Xamarin.Forms 页面。
  2. 布局 - Xamarin.Forms 布局是用于将视图组合到逻辑结构的容器。 Phoneword 应用程序使用 StackLayout 类以水平堆叠方式排列控件。 有关布局的详细信息,请参阅 Xamarin.Forms 布局。
  3. 视图 - Xamarin.Forms 视图是显示在用户界面上的控件,如标签、按钮和文本输入框。 Phoneword 应用程序使用LabelEntry 和 Button 控件。 有关视图的详细信息,请参阅 Xamarin.Forms 视图。
  4. 单元格 - Xamarin.Forms 单元格是专门用于列表中的项的元素,描述列表中每个项的绘制方式。 Phoneword 应用程序不会使用任何单元格。 有关单元格的详细信息,请参阅 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" />

Phoneword 中引入的其他概念

用于 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 体系结构和概念。

你可能感兴趣的:(Xamarin,xamarin.forms,Xamarin.Forms,跨平台新势力)