On May 28, 2014, Xamarin introduced Xamarin.Forms, which allows you to write user-interface code that can be compiled for the iOS, Android, and Windows devices. The Xamarin.Forms option Xamarin.Forms supports five distinct application platforms: iOS for programs that run on the iPhone, iPad, and iPod Touch. Android for programs that run on Android phones and tablets. The Universal Windows Platform (UWP) for applications that runs under Windows 10 or Windows 10 Mobile. The Windows Runtime API of Windows 8.1. The Windows Runtime API of Windows Phone 8.1. In this book, “Windows” or “Windows Phone” will generally be used as a generic term to describe all three of the Microsoft platforms.
原文
在2014年5月28日,Xamarin引入了Xamarin.Forms,通过它我们可以编写能够被IOS、Android和Windows编译的图形用户界面代码。
Xamarin.Forms支持5种不同的应用平台
- 运行在iPhone,iPad和IPod的iOS程序
- 运行在Android手机和平板的Android程序
- 运行在Windows10或Windows10 Mobile的UWP程序
- Windows 8.1运行时API
- Windows Phone 8.1运行时API
本书中,"Windows"或者"Windows Phone"通常作为一个通用的术语来描述微软所有的这三种平台。
In the general case, a Xamarin.Forms application in Visual Studio consists of five separate projects for each of these five platforms, with a sixth project containing common code. But the five platform projects in a Xamarin.Forms application are typically quite small—often consisting of just stubs with a little boilerplate startup code. The PCL or SAP contains the bulk of the application, including the user-interface code. The following diagram shows just the iOS, Android, and Universal Windows Platform. The other two Windows platforms are similar to UWP:
原文
通常情况下,VisualStudio中的一个Xamarin.Forms程序对于这5个不同的平台会包含5个独立的项目,另外还有第6个项目来包含公共代码。但是这5个平台的Xamarin.Forms应用程序都会非常小,常常就是包含了一个启动项的代码。PCL或者SAP中包含了大量的程序代码,包括用户界面代码。下图仅展示了iOS、Android和UWP平台,另外两个平台和UWP类似:
The Xamarin.Forms.Core and Xamarin.Forms.Xaml libraries implement the Xamarin.Forms API. Depending on the platform, Xamarin.Forms.Core then makes use of one of the Xamarin.Forms.Platform libraries. These libraries are mostly a collection of classes called renderers that transform the Xamarin.Forms user-interface objects into the platform-specific user interface. The remainder of the diagram is the same as the one shown earlier. For example, suppose you need the user-interface object discussed earlier that allows the user to toggle a Boolean value. When programming for Xamarin.Forms, this is called a Switch, and a class named Switch is implemented in the Xamarin.Forms.Core library. In the individual renderers for the three platforms, this Switch is mapped to a UISwitch on the iPhone, a Switch on Android, and a ToggleSwitch on Windows Phone. Xamarin.Forms.Core also contains a class named Slider for displaying a horizontal bar that the user manipulates to choose a numeric value. In the renderers in the platform-specific libraries, this is mapped to a UISlider on the iPhone, a SeekBar on Android, and a Slider on Windows Phone. This means that when you write a Xamarin.Forms program that has a Switch or a Slider, what’s actually displayed is the corresponding object implemented in each platform. Here’s a little Xamarin.Forms program containing a Label reading “Hello, Xamarin.Forms!”, a Button saying “Click Me!”, a Switch, and a Slider. The program is running on (from left to right) the iPhone, an Android phone, and a Windows 10 Mobile device:
原文
Xamarin.Forms.Core和Xamarin.Forms.Xaml库实现了Xamarin.Forms的API。Xamarin.Forms.Core使用Xamarin.Forms.Platform类库中的一个。这些类库包含了将Xamarin.Forms用户界面对象转换为特定平台用户界面对象众多类的集合。
该图剩下的部分和上一篇文章中的图片所述的内容一样。
例如,假设你需要实现之前讨论的,一个开关功能的用户界面。在Xamarin.Forms编程中,使用的是Switch,它在Xamarin.Forms.Core类库中被一个叫Switch的类实现。这三个平台有各自的呈现方式,在iPhone中会映射成一个UISwitch,Android上是Switch,WP上面是ToggleSwitch。
Xamarin.Forms.Core中也包含一个叫做Slider的类,用于显示一个水平的条,用户可以在上面进行滑动来选择一个数值。渲染到特定平台类库的时候,在iPhone中映射到UISlider,Android中的是SeekBar,WP中是Slider。
这意味着,当你开发一个Xamarin.Forms程序,包含了一个开关和一个滑块。最终在每个不同的平台上真实展示出来对应的对象是什么。
下面讲一个小的Xamarin.Forms程序,包含一个标签,内容是“Hello,Xamarin.Forms!”,一个按钮“Click Me”,还有一个开关和一个滑块。下图从左到右依次是程序运行在iPhone、Android和Windows10移动设备上面的效果(从左到右,越来越丑,有木有)。
The iPhone screenshot is of an iPhone 6 simulator running iOS 9.2. The Android phone is an LG Nexus 5 running Android version 6. The Windows 10 Mobile device is a Nokia Lumia 935 running a Windows 10 Technical Preview. You’ll encounter triple screenshots like this one throughout this book. They’re always in the same order—iPhone, Android, and Windows 10 Mobile—and they’re always running the same program. As you can see, the Button, Switch, and Slider all have different appearances on the three phones because they are all rendered with the object specific to each platform. What’s even more interesting is the inclusion in this program of six ToolBarItem objects, three identified as primary items with icons, and three as secondary items without icons. On the iPhone theseare rendered with UIBarButtonItem objects as the three icons and three buttons at the top of the page. On the Android, the first three are rendered as items on an ActionBar, also at the top of the page. On Windows 10 Mobile, they’re realized as items on the CommandBar at the page’s bottom. The Android ActionBar has a vertical ellipsis and the Universal Windows Platform CommandBar has a horizontal ellipsis. Tapping this ellipsis causes the secondary items to be displayed in a manner appropriate to these two platforms:
原文
iPhone截图来自于运行了IOS9.2的iPhone6 s,Android手机是运行Andorra 6.0的三星Nexus 5,Windows 10设备是运行Windows 10技术预览版的Lumia 935。
这本书中,你会看到很多这样的包含三个设备例子,都是相同的顺序:iPhone,Android和Windows 10 Mobile,并且运行同样的程序。
你会发现,按钮、开关和滑块在这个三个手机上有不同的外观,因为它们是被每一个特定平台的对象所呈现。
更有趣的是,在这个程序中包含了六个工具栏对象,三个带图标的一级菜单项和三个二级菜单项。在iPhone设备中,使用UIBarButtonItem对象将三个图标和三个按钮呈现在页面的顶部。在Android中,这三个菜单项使用ActionBar呈现,也是在页面的顶部。在Windows 10 Moblie中,使用CommandBar实现这些菜单项,显示在页面底部。
Android的ActionBar有一个垂直的省略号,UWP平台的CommandBar有一个水平的省略号。点击这个省略号可以让二级菜单以合适于这两个平台的方式显示出来。
Xamarin.Forms最初的设计为手机提供一个平台无关的API,然而现在Xamarin.Forms不仅仅限制于手机。下面是同样的程序运行在iPad Ari 2模拟器中的效果。
Most of the programs in this book are fairly simple, and hence designed to look their best on a phone screen in portrait mode. But they will also run in landscape mode and on tablets. Here’s the UWP project on a Microsoft Surface Pro 3 running Windows 10:
原文
这本书中的大部分程序都非常简单,并且最好是以纵向模式进行设计,但是也可以按横向模式运行或者运行在平板上面。下面是在安装Windows 10系统的Microsoft Surface Pro 3设备上运行的一个UWP项目。
Notice the toolbar at the top of the screen. The ellipsis has already been pressed to reveal the three secondary items. The other two platforms supported by Xamarin.Forms are Windows 8.1 and Windows Phone 8.1. Here’s the Windows 8.1 program running in a window on the Windows 10 desktop, and the Windows 8.1 program running on the Windows 10 Mobile device:
原文
注意屏幕顶端的工具栏,省略号被点击后显示出的三个二级工具栏。Xamarin.Forms支持的另外两个平台Windows 8.1和Windows Phone 8.1,下图是Windows8.1程序运行在Windows10桌面系统和Windows10移动设备上的效果。
The Windows 8.1 screen has been left-clicked with the mouse to reveal the toolbar items at the bottom. On this screen, the secondary items are at the left, but the program neglectfully forgot to assign them icons. On the Windows Phone 8.1 screen, the ellipsis at the bottom has been pressed. The various implementations of the toolbar reveals that, in one sense, Xamarin.Forms is an API that virtualizes not only the user-interface elements on each platform, but also the user-interface paradigms.
原文
在我们鼠标右击Windows8.1屏幕的时候,工具栏显示在屏幕的底部,二级工具栏显示在右侧,但是没有图标。在WP 8.1中,需要点击省略号调出二级工具栏。工具栏的种种现象表明了Xamarin.Forms作为一个API不仅仅将用户界面元素映射到各个平台,同时还有用户界面范式
支持XAML
Xamarin.Forms also supports XAML (pronounced “zammel” to rhyme with “camel”), the XML-based Extensible Application Markup Language developed at Microsoft as a general-purpose markup language for instantiating and initializing objects. XAML isn’t limited to defining initial layouts of user interfaces, but historically that’s how it’s been used the most, and that’s what it’s used for in Xamarin.Forms. Here’s the XAML file for the program whose screenshots you’ve just seen:
原文
Xamarin.Forms还支持XAML(基于XML的可扩展应用程序标记语言),是微软开发的用于实例化和初始化对象的通用标记语言。XAML不局限于定义用户界面的最初布局,但是历史上这是被利用最多的地方,也被Xamarin.Forms使用。
下面是上面你看到程序的XAML截图
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="PlatformVisuals.PlatformVisualsPage" Title="Visuals"> <StackLayout Padding="10,0"> <Label Text="Hello, Xamarin.Forms!" FontSize="Large" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" /> HorizontalOptions="Center" /> <Button Text = "Click Me!" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" /> <Switch VerticalOptions="CenterAndExpand" HorizontalOptions="Center" /> <Slider VerticalOptions="CenterAndExpand" /> </StackLayout> <ContentPage.ToolbarItems> <ToolbarItem Text="edit" Order="Primary"> <ToolbarItem.Icon> <OnPlatform x:TypeArguments="FileImageSource" iOS="edit.png" Android="ic_action_edit.png" WinPhone="Images/edit.png" /> </ToolbarItem.Icon> </ToolbarItem> <ToolbarItem Text="search" Order="Primary"> <ToolbarItem.Icon> <OnPlatform x:TypeArguments="FileImageSource" iOS="search.png" Android="ic_action_search.png" WinPhone="Images/feature.search.png" /> </ToolbarItem.Icon> </ToolbarItem> <ToolbarItem Text="refresh" Order="Primary"> <ToolbarItem.Icon> <OnPlatform x:TypeArguments="FileImageSource" iOS="reload.png" Android="ic_action_refresh.png" WinPhone="Images/refresh.png" /> </ToolbarItem.Icon> </ToolbarItem> <ToolbarItem Text="explore" Order="Secondary" /> <ToolbarItem Text="discover" Order="Secondary" /> <ToolbarItem Text="evolve" Order="Secondary" /> </ContentPage.ToolbarItems> </ContentPage>
Unless you have experience with XAML, some syntax details might be a little obscure. (Don’t worry; you’ll learn all about them later on in this book.) But even so, you can see the Label, Button, Switch, and Slider tags. In a real program, the Button, Switch, and Slider would probably have event handlers attached that would be implemented in a C# code file. Here they do not. The VerticalOptions and HorizontalOptions attributes assist in layout; they are discussed in the next chapter.
原文
除非你有XAML的相关经验,一些语法细节可能有点晦涩难懂,这本书的后面会有详细的介绍。即便如此,你也能从中找出Label、Button、Switch和Slider标签。在一个真实的程序中,像Button、Switch和Slider这些控件都会有采用C#代码编写的事件处理程序。VerticalOptions和HorizontalOptions属性用于辅助布局。它们都会在下一章节进行讨论。
平台特异性
In the section of that XAML file involving the ToolbarItem, you can also see a tag named OnPlatform. This is one of several techniques in Xamarin.Forms that allow introducing some platform specificity in otherwise platform-independent code or markup. It’s used here because each of the separate platforms has somewhat different image format and size requirements associated with these icons. A similar facility exists in code with the Device class. It’s possible to determine what platform the code is running on and to choose values or objects based on the platform. For example, you can specify different font sizes for each platform or run different blocks of code based on the platform. You might want to let the user manipulate a Slider to select a value in one platform but pick a number from a set of explicit values in another platform. In some applications, deeper platform specificities might be desired. For example, suppose your application requires the GPS coordinates of the user’s phone. This is not something that Xamarin.Forms provides, so you’d need to write your own code specific to each platform to obtain this information. The DependencyService class provides a way to do this in a structured manner. You define an interface with the methods you need (for example, IGetCurrentLocation) and then implement that interface with a class in each of the platform projects. You can then call the methods in that interface from the Xamarin.Forms project almost as easily as if it were part of the API. Each of the standard Xamarin.Forms visual objects—such as Label, Button, Switch, and Slider—are supported by a renderer class in the various Xamarin.Forms.Platform libraries. Each renderer class implements the platform-specific object that maps to the Xamarin.Forms object. You can create your own custom visual objects with your own custom renderers. The custom visual object goes in the common code project, and the custom renderers go in the individual platform projects. To make it a bit easier, generally you’ll want to derive from an existing class. Within the individual Xamarin.Forms platform libraries, all the corresponding renderers are public classes, and you can derive from them as well. Xamarin.Forms allows you to be as platform independent or as platform specific as you need to be. Xamarin.Forms doesn’t replace Xamarin.iOS and Xamarin.Android; rather, it integrates with them.
原文
在XAML文件中,有一个ToolbarItem配置节,你可以看到OnPlatform标签。这是Xamarin.Forms将一些平台特性引入到其他平台无关的代码或标记中的几种方法之一。这里使用的原因,是每个独立的平台对于图标有着不太一样的图片格式和尺寸要求。
与上面标签类似的机制可能存在于一个叫做Device的类的代码中。这个类会根据具体的平台,去决定运行怎样的平台代码以及选择对象和值。例如,你可以为每个平台指定不同的字体大小或者基于平台运行不同的代码块。或许你希望用户在一个平台下可以通过操纵滑块来选择一个值,而在另外一个平台中是通过一个有着精确值的集合去挑选一个值。
在某些应用程序中,可能需要一些更深入的平台特异性。例如,假设你的应用程序需要用户手机的GPS坐标。这不是Xamarin.Forms提供的,所以你需要编写你自己的代码,具体到每一个平台来获得这些消息。
DependencyService类提供一种结构化的方式实现上面这个功能,你可以定义一个你所要方法的接口(比如:IGetCurrentLocation),然后在每个平台项目中使用类去实现它。然后可以很容易的从Xamarin.Forms调用接口的方法,就如同API的一部分。
Xamarin.Forms中每一个标准的可视化对象,如:Label、Button、Switch和Slider,是被Xamarin.Forms.Platform类库中的渲染类所支持。每一个渲染类将特定平台对象映射到Xamarin.Forms对象。
你可以使用自定义的渲染器来创建自己的可视化对象,自定义的可视化对象写在公共代码项目中,然后通过各自的目标平台去应用。为了让这个操作更容易一些,通常你会考虑从现有的类进行派生。在各个Xamarin.Forms平台类库,所有和渲染相关的都是公共类,可以很容易从中派生。
Xamarin.Forms可以开发平台无关或者平台相关的项目,但是它不仅仅是代替Xamarin.Android和Xamarin.IOS,它集成了这两者。
跨平台的万灵药
For the most part, Xamarin.Forms defines its abstractions with a focus on areas of the mobile user interface that are common to the iOS, Android, and Windows Runtime APIs. These Xamarin.Forms visual objects are mapped to platform-specific objects, but Xamarin.Forms has tended to avoid implementing anything that is unique to a particular platform. For this reason, despite the enormous help that Xamarin.Forms can offer in creating platform-independent applications, it is not a complete replacement for native API programming. If your application relies heavily on native API features such as particular types of controls or widgets, then you might want to stick with Xamarin.iOS, Xamarin.Android, and the native Windows Phone API. You’ll probably also want to stick with the native APIs for applications that require vector graphics or complex touch interaction. The current version of Xamarin.Forms is not quite ready for these scenarios. On the other hand, Xamarin.Forms is great for prototyping or making a quick proof-of-concept application. And after you’ve done that, you might just find that you can continue using Xamarin.Forms features to build the entire application. Xamarin.Forms is ideal for line-of-business applications. Even if you begin building an application with Xamarin.Forms and then implement major parts of it with platform APIs, you’re doing so within a framework that allows you to share code and that offers structured ways to make platform-specific visuals.
原文
大多数情况下,Xamarin.Forms定义它的抽象会关注一个焦点:对于iOS、Android和Windows运行时API通用的移动用户界面。Xamarin.Forms可视化对象被映射成特定平台的对象,但是Xamarin.Forms倾向于避免使用特定平台下面某个平台特有的内容。
正是由于这个原因,尽管Xamarin.Forms在创建平台无关应用程序上提供了极大的便利,但是它不能完全替代原生API编程。如果你的应用程序高度依赖于原生API特性,如:特定类型的控件或小部件,那么你可能需要使用Xamarin.iOS、Xamarin.Android或原生的Windows Phone API。
你可能想调用原生API来让实现一个矢量图形或复杂触摸交互的应用程序,目前版本的Xamarin.Forms还不能提供完全的解决方案。
另一方面,Xamarin.Forms适合原型制作和快速概念证明的应用程序,当实现后这样的应用之后,你就能继续使用Xamarin.Forms的特性实现一个完整的应用。Xamarin.Forms是一个理想的实现手段对于业务线应用程序。
即使你开始用Xamarin.Forms构建一个应用程序,然后使用平台API实现主要部分。你需要实现一个框架允许你共享代码和提供结构化的方法实现特定平台的效果。